1276479Sdim//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2249261Sdim//
3249261Sdim//                     The LLVM Compiler Infrastructure
4249261Sdim//
5249261Sdim// This file is distributed under the University of Illinois Open Source
6249261Sdim// License. See LICENSE.TXT for details.
7249261Sdim//
8249261Sdim//===----------------------------------------------------------------------===//
9249261Sdim/// \file
10249261Sdim/// \brief This file implements semantic analysis for OpenMP directives and
11261991Sdim/// clauses.
12249261Sdim///
13249261Sdim//===----------------------------------------------------------------------===//
14249261Sdim
15288943Sdim#include "TreeTransform.h"
16276479Sdim#include "clang/AST/ASTContext.h"
17280031Sdim#include "clang/AST/ASTMutationListener.h"
18249261Sdim#include "clang/AST/Decl.h"
19261991Sdim#include "clang/AST/DeclCXX.h"
20249261Sdim#include "clang/AST/DeclOpenMP.h"
21261991Sdim#include "clang/AST/StmtCXX.h"
22261991Sdim#include "clang/AST/StmtOpenMP.h"
23261991Sdim#include "clang/AST/StmtVisitor.h"
24276479Sdim#include "clang/Basic/OpenMPKinds.h"
25288943Sdim#include "clang/Basic/TargetInfo.h"
26249261Sdim#include "clang/Lex/Preprocessor.h"
27261991Sdim#include "clang/Sema/Initialization.h"
28249261Sdim#include "clang/Sema/Lookup.h"
29261991Sdim#include "clang/Sema/Scope.h"
30261991Sdim#include "clang/Sema/ScopeInfo.h"
31276479Sdim#include "clang/Sema/SemaInternal.h"
32249261Sdimusing namespace clang;
33249261Sdim
34261991Sdim//===----------------------------------------------------------------------===//
35261991Sdim// Stack of data-sharing attributes for variables
36261991Sdim//===----------------------------------------------------------------------===//
37261991Sdim
38249261Sdimnamespace {
39261991Sdim/// \brief Default data sharing attributes, which can be applied to directive.
40261991Sdimenum DefaultDataSharingAttributes {
41276479Sdim  DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
42276479Sdim  DSA_none = 1 << 0,   /// \brief Default data sharing attribute 'none'.
43276479Sdim  DSA_shared = 1 << 1  /// \brief Default data sharing attribute 'shared'.
44261991Sdim};
45249261Sdim
46276479Sdimtemplate <class T> struct MatchesAny {
47276479Sdim  explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {}
48276479Sdim  bool operator()(T Kind) {
49276479Sdim    for (auto KindEl : Arr)
50276479Sdim      if (KindEl == Kind)
51276479Sdim        return true;
52276479Sdim    return false;
53276479Sdim  }
54276479Sdim
55276479Sdimprivate:
56276479Sdim  ArrayRef<T> Arr;
57276479Sdim};
58276479Sdimstruct MatchesAlways {
59276479Sdim  MatchesAlways() {}
60276479Sdim  template <class T> bool operator()(T) { return true; }
61276479Sdim};
62276479Sdim
63276479Sdimtypedef MatchesAny<OpenMPClauseKind> MatchesAnyClause;
64276479Sdimtypedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective;
65276479Sdim
66261991Sdim/// \brief Stack for tracking declarations used in OpenMP directives and
67261991Sdim/// clauses and their data-sharing attributes.
68261991Sdimclass DSAStackTy {
69261991Sdimpublic:
70261991Sdim  struct DSAVarData {
71261991Sdim    OpenMPDirectiveKind DKind;
72261991Sdim    OpenMPClauseKind CKind;
73261991Sdim    DeclRefExpr *RefExpr;
74276479Sdim    SourceLocation ImplicitDSALoc;
75276479Sdim    DSAVarData()
76276479Sdim        : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr),
77276479Sdim          ImplicitDSALoc() {}
78261991Sdim  };
79276479Sdim
80296417Sdimpublic:
81296417Sdim  struct MapInfo {
82296417Sdim    Expr *RefExpr;
83296417Sdim  };
84296417Sdim
85261991Sdimprivate:
86261991Sdim  struct DSAInfo {
87261991Sdim    OpenMPClauseKind Attributes;
88261991Sdim    DeclRefExpr *RefExpr;
89261991Sdim  };
90261991Sdim  typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
91276479Sdim  typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
92296417Sdim  typedef llvm::DenseMap<VarDecl *, unsigned> LoopControlVariablesMapTy;
93296417Sdim  typedef llvm::SmallDenseMap<VarDecl *, MapInfo, 64> MappedDeclsTy;
94296417Sdim  typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
95296417Sdim      CriticalsWithHintsTy;
96261991Sdim
97261991Sdim  struct SharingMapTy {
98261991Sdim    DeclSAMapTy SharingMap;
99276479Sdim    AlignedMapTy AlignedMap;
100296417Sdim    MappedDeclsTy MappedDecls;
101296417Sdim    LoopControlVariablesMapTy LCVMap;
102261991Sdim    DefaultDataSharingAttributes DefaultAttr;
103276479Sdim    SourceLocation DefaultAttrLoc;
104261991Sdim    OpenMPDirectiveKind Directive;
105261991Sdim    DeclarationNameInfo DirectiveName;
106261991Sdim    Scope *CurScope;
107276479Sdim    SourceLocation ConstructLoc;
108296417Sdim    /// \brief first argument (Expr *) contains optional argument of the
109296417Sdim    /// 'ordered' clause, the second one is true if the regions has 'ordered'
110296417Sdim    /// clause, false otherwise.
111296417Sdim    llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
112288943Sdim    bool NowaitRegion;
113296417Sdim    bool CancelRegion;
114296417Sdim    unsigned AssociatedLoops;
115280031Sdim    SourceLocation InnerTeamsRegionLoc;
116276479Sdim    SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
117276479Sdim                 Scope *CurScope, SourceLocation Loc)
118296417Sdim        : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified),
119276479Sdim          Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
120296417Sdim          ConstructLoc(Loc), OrderedRegion(), NowaitRegion(false),
121296417Sdim          CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {}
122261991Sdim    SharingMapTy()
123296417Sdim        : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified),
124276479Sdim          Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
125296417Sdim          ConstructLoc(), OrderedRegion(), NowaitRegion(false),
126296417Sdim          CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {}
127261991Sdim  };
128261991Sdim
129261991Sdim  typedef SmallVector<SharingMapTy, 64> StackTy;
130261991Sdim
131261991Sdim  /// \brief Stack of used declaration and their data-sharing attributes.
132261991Sdim  StackTy Stack;
133288943Sdim  /// \brief true, if check for DSA must be from parent directive, false, if
134288943Sdim  /// from current directive.
135288943Sdim  OpenMPClauseKind ClauseKindMode;
136276479Sdim  Sema &SemaRef;
137288943Sdim  bool ForceCapturing;
138296417Sdim  CriticalsWithHintsTy Criticals;
139261991Sdim
140261991Sdim  typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
141261991Sdim
142261991Sdim  DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D);
143276479Sdim
144276479Sdim  /// \brief Checks if the variable is a local for OpenMP region.
145276479Sdim  bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
146276479Sdim
147261991Sdimpublic:
148288943Sdim  explicit DSAStackTy(Sema &S)
149288943Sdim      : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S),
150288943Sdim        ForceCapturing(false) {}
151261991Sdim
152288943Sdim  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
153288943Sdim  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
154288943Sdim
155288943Sdim  bool isForceVarCapturing() const { return ForceCapturing; }
156288943Sdim  void setForceVarCapturing(bool V) { ForceCapturing = V; }
157288943Sdim
158261991Sdim  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
159276479Sdim            Scope *CurScope, SourceLocation Loc) {
160276479Sdim    Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
161276479Sdim    Stack.back().DefaultAttrLoc = Loc;
162261991Sdim  }
163261991Sdim
164261991Sdim  void pop() {
165261991Sdim    assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!");
166261991Sdim    Stack.pop_back();
167261991Sdim  }
168261991Sdim
169296417Sdim  void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) {
170296417Sdim    Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint);
171296417Sdim  }
172296417Sdim  const std::pair<OMPCriticalDirective *, llvm::APSInt>
173296417Sdim  getCriticalWithHint(const DeclarationNameInfo &Name) const {
174296417Sdim    auto I = Criticals.find(Name.getAsString());
175296417Sdim    if (I != Criticals.end())
176296417Sdim      return I->second;
177296417Sdim    return std::make_pair(nullptr, llvm::APSInt());
178296417Sdim  }
179276479Sdim  /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
180276479Sdim  /// add it and return NULL; otherwise return previous occurrence's expression
181276479Sdim  /// for diagnostics.
182276479Sdim  DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE);
183276479Sdim
184288943Sdim  /// \brief Register specified variable as loop control variable.
185288943Sdim  void addLoopControlVariable(VarDecl *D);
186288943Sdim  /// \brief Check if the specified variable is a loop control variable for
187288943Sdim  /// current region.
188296417Sdim  /// \return The index of the loop control variable in the list of associated
189296417Sdim  /// for-loops (from outer to inner).
190296417Sdim  unsigned isLoopControlVariable(VarDecl *D);
191296417Sdim  /// \brief Check if the specified variable is a loop control variable for
192296417Sdim  /// parent region.
193296417Sdim  /// \return The index of the loop control variable in the list of associated
194296417Sdim  /// for-loops (from outer to inner).
195296417Sdim  unsigned isParentLoopControlVariable(VarDecl *D);
196296417Sdim  /// \brief Get the loop control variable for the I-th loop (or nullptr) in
197296417Sdim  /// parent directive.
198296417Sdim  VarDecl *getParentLoopControlVariable(unsigned I);
199288943Sdim
200261991Sdim  /// \brief Adds explicit data sharing attribute to the specified declaration.
201261991Sdim  void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
202261991Sdim
203261991Sdim  /// \brief Returns data sharing attributes from top of the stack for the
204261991Sdim  /// specified declaration.
205276479Sdim  DSAVarData getTopDSA(VarDecl *D, bool FromParent);
206261991Sdim  /// \brief Returns data-sharing attributes for the specified declaration.
207276479Sdim  DSAVarData getImplicitDSA(VarDecl *D, bool FromParent);
208276479Sdim  /// \brief Checks if the specified variables has data-sharing attributes which
209276479Sdim  /// match specified \a CPred predicate in any directive which matches \a DPred
210276479Sdim  /// predicate.
211276479Sdim  template <class ClausesPredicate, class DirectivesPredicate>
212276479Sdim  DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred,
213276479Sdim                    DirectivesPredicate DPred, bool FromParent);
214276479Sdim  /// \brief Checks if the specified variables has data-sharing attributes which
215276479Sdim  /// match specified \a CPred predicate in any innermost directive which
216276479Sdim  /// matches \a DPred predicate.
217276479Sdim  template <class ClausesPredicate, class DirectivesPredicate>
218276479Sdim  DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
219276479Sdim                             DirectivesPredicate DPred,
220276479Sdim                             bool FromParent);
221288943Sdim  /// \brief Checks if the specified variables has explicit data-sharing
222288943Sdim  /// attributes which match specified \a CPred predicate at the specified
223288943Sdim  /// OpenMP region.
224288943Sdim  bool hasExplicitDSA(VarDecl *D,
225288943Sdim                      const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
226288943Sdim                      unsigned Level);
227296417Sdim
228296417Sdim  /// \brief Returns true if the directive at level \Level matches in the
229296417Sdim  /// specified \a DPred predicate.
230296417Sdim  bool hasExplicitDirective(
231296417Sdim      const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
232296417Sdim      unsigned Level);
233296417Sdim
234276479Sdim  /// \brief Finds a directive which matches specified \a DPred predicate.
235276479Sdim  template <class NamedDirectivesPredicate>
236276479Sdim  bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent);
237261991Sdim
238261991Sdim  /// \brief Returns currently analyzed directive.
239261991Sdim  OpenMPDirectiveKind getCurrentDirective() const {
240261991Sdim    return Stack.back().Directive;
241261991Sdim  }
242276479Sdim  /// \brief Returns parent directive.
243276479Sdim  OpenMPDirectiveKind getParentDirective() const {
244276479Sdim    if (Stack.size() > 2)
245276479Sdim      return Stack[Stack.size() - 2].Directive;
246276479Sdim    return OMPD_unknown;
247276479Sdim  }
248296417Sdim  /// \brief Return the directive associated with the provided scope.
249296417Sdim  OpenMPDirectiveKind getDirectiveForScope(const Scope *S) const;
250261991Sdim
251261991Sdim  /// \brief Set default data sharing attribute to none.
252276479Sdim  void setDefaultDSANone(SourceLocation Loc) {
253276479Sdim    Stack.back().DefaultAttr = DSA_none;
254276479Sdim    Stack.back().DefaultAttrLoc = Loc;
255276479Sdim  }
256261991Sdim  /// \brief Set default data sharing attribute to shared.
257276479Sdim  void setDefaultDSAShared(SourceLocation Loc) {
258276479Sdim    Stack.back().DefaultAttr = DSA_shared;
259276479Sdim    Stack.back().DefaultAttrLoc = Loc;
260276479Sdim  }
261261991Sdim
262261991Sdim  DefaultDataSharingAttributes getDefaultDSA() const {
263261991Sdim    return Stack.back().DefaultAttr;
264261991Sdim  }
265276479Sdim  SourceLocation getDefaultDSALocation() const {
266276479Sdim    return Stack.back().DefaultAttrLoc;
267276479Sdim  }
268261991Sdim
269276479Sdim  /// \brief Checks if the specified variable is a threadprivate.
270276479Sdim  bool isThreadPrivate(VarDecl *D) {
271276479Sdim    DSAVarData DVar = getTopDSA(D, false);
272276479Sdim    return isOpenMPThreadPrivate(DVar.CKind);
273276479Sdim  }
274276479Sdim
275280031Sdim  /// \brief Marks current region as ordered (it has an 'ordered' clause).
276296417Sdim  void setOrderedRegion(bool IsOrdered, Expr *Param) {
277296417Sdim    Stack.back().OrderedRegion.setInt(IsOrdered);
278296417Sdim    Stack.back().OrderedRegion.setPointer(Param);
279280031Sdim  }
280280031Sdim  /// \brief Returns true, if parent region is ordered (has associated
281280031Sdim  /// 'ordered' clause), false - otherwise.
282280031Sdim  bool isParentOrderedRegion() const {
283280031Sdim    if (Stack.size() > 2)
284296417Sdim      return Stack[Stack.size() - 2].OrderedRegion.getInt();
285280031Sdim    return false;
286280031Sdim  }
287296417Sdim  /// \brief Returns optional parameter for the ordered region.
288296417Sdim  Expr *getParentOrderedRegionParam() const {
289296417Sdim    if (Stack.size() > 2)
290296417Sdim      return Stack[Stack.size() - 2].OrderedRegion.getPointer();
291296417Sdim    return nullptr;
292296417Sdim  }
293288943Sdim  /// \brief Marks current region as nowait (it has a 'nowait' clause).
294288943Sdim  void setNowaitRegion(bool IsNowait = true) {
295288943Sdim    Stack.back().NowaitRegion = IsNowait;
296288943Sdim  }
297288943Sdim  /// \brief Returns true, if parent region is nowait (has associated
298288943Sdim  /// 'nowait' clause), false - otherwise.
299288943Sdim  bool isParentNowaitRegion() const {
300288943Sdim    if (Stack.size() > 2)
301288943Sdim      return Stack[Stack.size() - 2].NowaitRegion;
302288943Sdim    return false;
303288943Sdim  }
304296417Sdim  /// \brief Marks parent region as cancel region.
305296417Sdim  void setParentCancelRegion(bool Cancel = true) {
306296417Sdim    if (Stack.size() > 2)
307296417Sdim      Stack[Stack.size() - 2].CancelRegion =
308296417Sdim          Stack[Stack.size() - 2].CancelRegion || Cancel;
309296417Sdim  }
310296417Sdim  /// \brief Return true if current region has inner cancel construct.
311296417Sdim  bool isCancelRegion() const {
312296417Sdim    return Stack.back().CancelRegion;
313296417Sdim  }
314280031Sdim
315288943Sdim  /// \brief Set collapse value for the region.
316296417Sdim  void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; }
317288943Sdim  /// \brief Return collapse value for region.
318296417Sdim  unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; }
319288943Sdim
320280031Sdim  /// \brief Marks current target region as one with closely nested teams
321280031Sdim  /// region.
322280031Sdim  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
323280031Sdim    if (Stack.size() > 2)
324280031Sdim      Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc;
325280031Sdim  }
326280031Sdim  /// \brief Returns true, if current region has closely nested teams region.
327280031Sdim  bool hasInnerTeamsRegion() const {
328280031Sdim    return getInnerTeamsRegionLoc().isValid();
329280031Sdim  }
330280031Sdim  /// \brief Returns location of the nested teams region (if any).
331280031Sdim  SourceLocation getInnerTeamsRegionLoc() const {
332280031Sdim    if (Stack.size() > 1)
333280031Sdim      return Stack.back().InnerTeamsRegionLoc;
334280031Sdim    return SourceLocation();
335280031Sdim  }
336280031Sdim
337276479Sdim  Scope *getCurScope() const { return Stack.back().CurScope; }
338261991Sdim  Scope *getCurScope() { return Stack.back().CurScope; }
339276479Sdim  SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
340296417Sdim
341296417Sdim  MapInfo getMapInfoForVar(VarDecl *VD) {
342296417Sdim    MapInfo VarMI = {0};
343296417Sdim    for (auto Cnt = Stack.size() - 1; Cnt > 0; --Cnt) {
344296417Sdim      if (Stack[Cnt].MappedDecls.count(VD)) {
345296417Sdim        VarMI = Stack[Cnt].MappedDecls[VD];
346296417Sdim        break;
347296417Sdim      }
348296417Sdim    }
349296417Sdim    return VarMI;
350296417Sdim  }
351296417Sdim
352296417Sdim  void addMapInfoForVar(VarDecl *VD, MapInfo MI) {
353296417Sdim    if (Stack.size() > 1) {
354296417Sdim      Stack.back().MappedDecls[VD] = MI;
355296417Sdim    }
356296417Sdim  }
357296417Sdim
358296417Sdim  MapInfo IsMappedInCurrentRegion(VarDecl *VD) {
359296417Sdim    assert(Stack.size() > 1 && "Target level is 0");
360296417Sdim    MapInfo VarMI = {0};
361296417Sdim    if (Stack.size() > 1 && Stack.back().MappedDecls.count(VD)) {
362296417Sdim      VarMI = Stack.back().MappedDecls[VD];
363296417Sdim    }
364296417Sdim    return VarMI;
365296417Sdim  }
366261991Sdim};
367276479Sdimbool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
368276479Sdim  return isOpenMPParallelDirective(DKind) || DKind == OMPD_task ||
369296417Sdim         isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown ||
370296417Sdim         isOpenMPTaskLoopDirective(DKind);
371276479Sdim}
372276479Sdim} // namespace
373261991Sdim
374261991SdimDSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
375261991Sdim                                          VarDecl *D) {
376288943Sdim  D = D->getCanonicalDecl();
377261991Sdim  DSAVarData DVar;
378276479Sdim  if (Iter == std::prev(Stack.rend())) {
379261991Sdim    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
380261991Sdim    // in a region but not in construct]
381261991Sdim    //  File-scope or namespace-scope variables referenced in called routines
382261991Sdim    //  in the region are shared unless they appear in a threadprivate
383261991Sdim    //  directive.
384280031Sdim    if (!D->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
385261991Sdim      DVar.CKind = OMPC_shared;
386261991Sdim
387261991Sdim    // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
388261991Sdim    // in a region but not in construct]
389261991Sdim    //  Variables with static storage duration that are declared in called
390261991Sdim    //  routines in the region are shared.
391261991Sdim    if (D->hasGlobalStorage())
392261991Sdim      DVar.CKind = OMPC_shared;
393261991Sdim
394261991Sdim    return DVar;
395261991Sdim  }
396276479Sdim
397261991Sdim  DVar.DKind = Iter->Directive;
398276479Sdim  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
399276479Sdim  // in a Construct, C/C++, predetermined, p.1]
400276479Sdim  // Variables with automatic storage duration that are declared in a scope
401276479Sdim  // inside the construct are private.
402276479Sdim  if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() &&
403276479Sdim      (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
404276479Sdim    DVar.CKind = OMPC_private;
405276479Sdim    return DVar;
406276479Sdim  }
407276479Sdim
408261991Sdim  // Explicitly specified attributes and local variables with predetermined
409261991Sdim  // attributes.
410261991Sdim  if (Iter->SharingMap.count(D)) {
411261991Sdim    DVar.RefExpr = Iter->SharingMap[D].RefExpr;
412261991Sdim    DVar.CKind = Iter->SharingMap[D].Attributes;
413276479Sdim    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
414261991Sdim    return DVar;
415261991Sdim  }
416261991Sdim
417261991Sdim  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
418261991Sdim  // in a Construct, C/C++, implicitly determined, p.1]
419261991Sdim  //  In a parallel or task construct, the data-sharing attributes of these
420261991Sdim  //  variables are determined by the default clause, if present.
421261991Sdim  switch (Iter->DefaultAttr) {
422261991Sdim  case DSA_shared:
423261991Sdim    DVar.CKind = OMPC_shared;
424276479Sdim    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
425261991Sdim    return DVar;
426261991Sdim  case DSA_none:
427261991Sdim    return DVar;
428261991Sdim  case DSA_unspecified:
429261991Sdim    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
430261991Sdim    // in a Construct, implicitly determined, p.2]
431261991Sdim    //  In a parallel construct, if no default clause is present, these
432261991Sdim    //  variables are shared.
433276479Sdim    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
434280031Sdim    if (isOpenMPParallelDirective(DVar.DKind) ||
435280031Sdim        isOpenMPTeamsDirective(DVar.DKind)) {
436261991Sdim      DVar.CKind = OMPC_shared;
437261991Sdim      return DVar;
438261991Sdim    }
439261991Sdim
440261991Sdim    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
441261991Sdim    // in a Construct, implicitly determined, p.4]
442261991Sdim    //  In a task construct, if no default clause is present, a variable that in
443261991Sdim    //  the enclosing context is determined to be shared by all implicit tasks
444261991Sdim    //  bound to the current team is shared.
445261991Sdim    if (DVar.DKind == OMPD_task) {
446261991Sdim      DSAVarData DVarTemp;
447288943Sdim      for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend();
448261991Sdim           I != EE; ++I) {
449276479Sdim        // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
450276479Sdim        // Referenced
451261991Sdim        // in a Construct, implicitly determined, p.6]
452261991Sdim        //  In a task construct, if no default clause is present, a variable
453261991Sdim        //  whose data-sharing attribute is not determined by the rules above is
454261991Sdim        //  firstprivate.
455261991Sdim        DVarTemp = getDSA(I, D);
456261991Sdim        if (DVarTemp.CKind != OMPC_shared) {
457276479Sdim          DVar.RefExpr = nullptr;
458261991Sdim          DVar.DKind = OMPD_task;
459261991Sdim          DVar.CKind = OMPC_firstprivate;
460261991Sdim          return DVar;
461249261Sdim        }
462276479Sdim        if (isParallelOrTaskRegion(I->Directive))
463276479Sdim          break;
464249261Sdim      }
465261991Sdim      DVar.DKind = OMPD_task;
466261991Sdim      DVar.CKind =
467276479Sdim          (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
468261991Sdim      return DVar;
469261991Sdim    }
470261991Sdim  }
471261991Sdim  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
472261991Sdim  // in a Construct, implicitly determined, p.3]
473261991Sdim  //  For constructs other than task, if no default clause is present, these
474261991Sdim  //  variables inherit their data-sharing attributes from the enclosing
475261991Sdim  //  context.
476276479Sdim  return getDSA(std::next(Iter), D);
477249261Sdim}
478261991Sdim
479276479SdimDeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) {
480276479Sdim  assert(Stack.size() > 1 && "Data sharing attributes stack is empty");
481288943Sdim  D = D->getCanonicalDecl();
482276479Sdim  auto It = Stack.back().AlignedMap.find(D);
483276479Sdim  if (It == Stack.back().AlignedMap.end()) {
484276479Sdim    assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
485276479Sdim    Stack.back().AlignedMap[D] = NewDE;
486276479Sdim    return nullptr;
487276479Sdim  } else {
488276479Sdim    assert(It->second && "Unexpected nullptr expr in the aligned map");
489276479Sdim    return It->second;
490276479Sdim  }
491276479Sdim  return nullptr;
492276479Sdim}
493276479Sdim
494288943Sdimvoid DSAStackTy::addLoopControlVariable(VarDecl *D) {
495288943Sdim  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
496288943Sdim  D = D->getCanonicalDecl();
497296417Sdim  Stack.back().LCVMap.insert(std::make_pair(D, Stack.back().LCVMap.size() + 1));
498288943Sdim}
499288943Sdim
500296417Sdimunsigned DSAStackTy::isLoopControlVariable(VarDecl *D) {
501288943Sdim  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
502288943Sdim  D = D->getCanonicalDecl();
503296417Sdim  return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] : 0;
504288943Sdim}
505288943Sdim
506296417Sdimunsigned DSAStackTy::isParentLoopControlVariable(VarDecl *D) {
507296417Sdim  assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");
508296417Sdim  D = D->getCanonicalDecl();
509296417Sdim  return Stack[Stack.size() - 2].LCVMap.count(D) > 0
510296417Sdim             ? Stack[Stack.size() - 2].LCVMap[D]
511296417Sdim             : 0;
512296417Sdim}
513296417Sdim
514296417SdimVarDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) {
515296417Sdim  assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");
516296417Sdim  if (Stack[Stack.size() - 2].LCVMap.size() < I)
517296417Sdim    return nullptr;
518296417Sdim  for (auto &Pair : Stack[Stack.size() - 2].LCVMap) {
519296417Sdim    if (Pair.second == I)
520296417Sdim      return Pair.first;
521296417Sdim  }
522296417Sdim  return nullptr;
523296417Sdim}
524296417Sdim
525261991Sdimvoid DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
526288943Sdim  D = D->getCanonicalDecl();
527261991Sdim  if (A == OMPC_threadprivate) {
528261991Sdim    Stack[0].SharingMap[D].Attributes = A;
529261991Sdim    Stack[0].SharingMap[D].RefExpr = E;
530261991Sdim  } else {
531261991Sdim    assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
532261991Sdim    Stack.back().SharingMap[D].Attributes = A;
533261991Sdim    Stack.back().SharingMap[D].RefExpr = E;
534261991Sdim  }
535261991Sdim}
536261991Sdim
537276479Sdimbool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
538288943Sdim  D = D->getCanonicalDecl();
539276479Sdim  if (Stack.size() > 2) {
540276479Sdim    reverse_iterator I = Iter, E = std::prev(Stack.rend());
541276479Sdim    Scope *TopScope = nullptr;
542276479Sdim    while (I != E && !isParallelOrTaskRegion(I->Directive)) {
543276479Sdim      ++I;
544276479Sdim    }
545276479Sdim    if (I == E)
546276479Sdim      return false;
547276479Sdim    TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
548276479Sdim    Scope *CurScope = getCurScope();
549276479Sdim    while (CurScope != TopScope && !CurScope->isDeclScope(D)) {
550261991Sdim      CurScope = CurScope->getParent();
551276479Sdim    }
552276479Sdim    return CurScope != TopScope;
553261991Sdim  }
554276479Sdim  return false;
555261991Sdim}
556261991Sdim
557288943Sdim/// \brief Build a variable declaration for OpenMP loop iteration variable.
558288943Sdimstatic VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
559296417Sdim                             StringRef Name, const AttrVec *Attrs = nullptr) {
560288943Sdim  DeclContext *DC = SemaRef.CurContext;
561288943Sdim  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
562288943Sdim  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
563288943Sdim  VarDecl *Decl =
564288943Sdim      VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
565296417Sdim  if (Attrs) {
566296417Sdim    for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
567296417Sdim         I != E; ++I)
568296417Sdim      Decl->addAttr(*I);
569296417Sdim  }
570288943Sdim  Decl->setImplicit();
571288943Sdim  return Decl;
572288943Sdim}
573288943Sdim
574288943Sdimstatic DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
575288943Sdim                                     SourceLocation Loc,
576288943Sdim                                     bool RefersToCapture = false) {
577288943Sdim  D->setReferenced();
578288943Sdim  D->markUsed(S.Context);
579288943Sdim  return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
580288943Sdim                             SourceLocation(), D, RefersToCapture, Loc, Ty,
581288943Sdim                             VK_LValue);
582288943Sdim}
583288943Sdim
584276479SdimDSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
585288943Sdim  D = D->getCanonicalDecl();
586261991Sdim  DSAVarData DVar;
587261991Sdim
588261991Sdim  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
589261991Sdim  // in a Construct, C/C++, predetermined, p.1]
590261991Sdim  //  Variables appearing in threadprivate directives are threadprivate.
591288943Sdim  if ((D->getTLSKind() != VarDecl::TLS_None &&
592288943Sdim       !(D->hasAttr<OMPThreadPrivateDeclAttr>() &&
593288943Sdim         SemaRef.getLangOpts().OpenMPUseTLS &&
594288943Sdim         SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
595288943Sdim      (D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() &&
596288943Sdim       !D->isLocalVarDecl())) {
597288943Sdim    addDSA(D, buildDeclRefExpr(SemaRef, D, D->getType().getNonReferenceType(),
598288943Sdim                               D->getLocation()),
599288943Sdim           OMPC_threadprivate);
600261991Sdim  }
601261991Sdim  if (Stack[0].SharingMap.count(D)) {
602261991Sdim    DVar.RefExpr = Stack[0].SharingMap[D].RefExpr;
603261991Sdim    DVar.CKind = OMPC_threadprivate;
604261991Sdim    return DVar;
605261991Sdim  }
606261991Sdim
607261991Sdim  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
608296417Sdim  // in a Construct, C/C++, predetermined, p.4]
609296417Sdim  //  Static data members are shared.
610296417Sdim  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
611296417Sdim  // in a Construct, C/C++, predetermined, p.7]
612296417Sdim  //  Variables with static storage duration that are declared in a scope
613296417Sdim  //  inside the construct are shared.
614296417Sdim  if (D->isStaticDataMember()) {
615296417Sdim    DSAVarData DVarTemp =
616296417Sdim        hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent);
617296417Sdim    if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
618276479Sdim      return DVar;
619261991Sdim
620296417Sdim    DVar.CKind = OMPC_shared;
621296417Sdim    return DVar;
622261991Sdim  }
623261991Sdim
624261991Sdim  QualType Type = D->getType().getNonReferenceType().getCanonicalType();
625276479Sdim  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
626288943Sdim  Type = SemaRef.getASTContext().getBaseElementType(Type);
627261991Sdim  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
628261991Sdim  // in a Construct, C/C++, predetermined, p.6]
629261991Sdim  //  Variables with const qualified type having no mutable member are
630261991Sdim  //  shared.
631276479Sdim  CXXRecordDecl *RD =
632276479Sdim      SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
633296417Sdim  if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
634296417Sdim    if (auto *CTD = CTSD->getSpecializedTemplate())
635296417Sdim      RD = CTD->getTemplatedDecl();
636261991Sdim  if (IsConstant &&
637296417Sdim      !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
638296417Sdim        RD->hasMutableFields())) {
639261991Sdim    // Variables with const-qualified type having no mutable member may be
640261991Sdim    // listed in a firstprivate clause, even if they are static data members.
641276479Sdim    DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate),
642276479Sdim                                 MatchesAlways(), FromParent);
643261991Sdim    if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
644261991Sdim      return DVar;
645261991Sdim
646261991Sdim    DVar.CKind = OMPC_shared;
647261991Sdim    return DVar;
648261991Sdim  }
649261991Sdim
650261991Sdim  // Explicitly specified attributes and local variables with predetermined
651261991Sdim  // attributes.
652296417Sdim  auto StartI = std::next(Stack.rbegin());
653296417Sdim  auto EndI = std::prev(Stack.rend());
654296417Sdim  if (FromParent && StartI != EndI) {
655296417Sdim    StartI = std::next(StartI);
656296417Sdim  }
657276479Sdim  auto I = std::prev(StartI);
658276479Sdim  if (I->SharingMap.count(D)) {
659276479Sdim    DVar.RefExpr = I->SharingMap[D].RefExpr;
660276479Sdim    DVar.CKind = I->SharingMap[D].Attributes;
661276479Sdim    DVar.ImplicitDSALoc = I->DefaultAttrLoc;
662261991Sdim  }
663261991Sdim
664261991Sdim  return DVar;
665261991Sdim}
666261991Sdim
667276479SdimDSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D, bool FromParent) {
668288943Sdim  D = D->getCanonicalDecl();
669276479Sdim  auto StartI = Stack.rbegin();
670276479Sdim  auto EndI = std::prev(Stack.rend());
671276479Sdim  if (FromParent && StartI != EndI) {
672276479Sdim    StartI = std::next(StartI);
673276479Sdim  }
674276479Sdim  return getDSA(StartI, D);
675261991Sdim}
676261991Sdim
677276479Sdimtemplate <class ClausesPredicate, class DirectivesPredicate>
678276479SdimDSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred,
679276479Sdim                                          DirectivesPredicate DPred,
680276479Sdim                                          bool FromParent) {
681288943Sdim  D = D->getCanonicalDecl();
682276479Sdim  auto StartI = std::next(Stack.rbegin());
683276479Sdim  auto EndI = std::prev(Stack.rend());
684276479Sdim  if (FromParent && StartI != EndI) {
685276479Sdim    StartI = std::next(StartI);
686276479Sdim  }
687276479Sdim  for (auto I = StartI, EE = EndI; I != EE; ++I) {
688276479Sdim    if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
689276479Sdim      continue;
690261991Sdim    DSAVarData DVar = getDSA(I, D);
691276479Sdim    if (CPred(DVar.CKind))
692261991Sdim      return DVar;
693261991Sdim  }
694261991Sdim  return DSAVarData();
695261991Sdim}
696249261Sdim
697276479Sdimtemplate <class ClausesPredicate, class DirectivesPredicate>
698276479SdimDSAStackTy::DSAVarData
699276479SdimDSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
700276479Sdim                            DirectivesPredicate DPred, bool FromParent) {
701288943Sdim  D = D->getCanonicalDecl();
702276479Sdim  auto StartI = std::next(Stack.rbegin());
703276479Sdim  auto EndI = std::prev(Stack.rend());
704276479Sdim  if (FromParent && StartI != EndI) {
705276479Sdim    StartI = std::next(StartI);
706276479Sdim  }
707276479Sdim  for (auto I = StartI, EE = EndI; I != EE; ++I) {
708276479Sdim    if (!DPred(I->Directive))
709276479Sdim      break;
710276479Sdim    DSAVarData DVar = getDSA(I, D);
711276479Sdim    if (CPred(DVar.CKind))
712276479Sdim      return DVar;
713276479Sdim    return DSAVarData();
714276479Sdim  }
715276479Sdim  return DSAVarData();
716276479Sdim}
717276479Sdim
718288943Sdimbool DSAStackTy::hasExplicitDSA(
719288943Sdim    VarDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
720288943Sdim    unsigned Level) {
721288943Sdim  if (CPred(ClauseKindMode))
722288943Sdim    return true;
723288943Sdim  if (isClauseParsingMode())
724288943Sdim    ++Level;
725288943Sdim  D = D->getCanonicalDecl();
726288943Sdim  auto StartI = Stack.rbegin();
727288943Sdim  auto EndI = std::prev(Stack.rend());
728288943Sdim  if (std::distance(StartI, EndI) <= (int)Level)
729288943Sdim    return false;
730288943Sdim  std::advance(StartI, Level);
731288943Sdim  return (StartI->SharingMap.count(D) > 0) && StartI->SharingMap[D].RefExpr &&
732288943Sdim         CPred(StartI->SharingMap[D].Attributes);
733288943Sdim}
734288943Sdim
735296417Sdimbool DSAStackTy::hasExplicitDirective(
736296417Sdim    const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
737296417Sdim    unsigned Level) {
738296417Sdim  if (isClauseParsingMode())
739296417Sdim    ++Level;
740296417Sdim  auto StartI = Stack.rbegin();
741296417Sdim  auto EndI = std::prev(Stack.rend());
742296417Sdim  if (std::distance(StartI, EndI) <= (int)Level)
743296417Sdim    return false;
744296417Sdim  std::advance(StartI, Level);
745296417Sdim  return DPred(StartI->Directive);
746296417Sdim}
747296417Sdim
748276479Sdimtemplate <class NamedDirectivesPredicate>
749276479Sdimbool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) {
750276479Sdim  auto StartI = std::next(Stack.rbegin());
751276479Sdim  auto EndI = std::prev(Stack.rend());
752276479Sdim  if (FromParent && StartI != EndI) {
753276479Sdim    StartI = std::next(StartI);
754276479Sdim  }
755276479Sdim  for (auto I = StartI, EE = EndI; I != EE; ++I) {
756276479Sdim    if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
757276479Sdim      return true;
758276479Sdim  }
759276479Sdim  return false;
760276479Sdim}
761276479Sdim
762296417SdimOpenMPDirectiveKind DSAStackTy::getDirectiveForScope(const Scope *S) const {
763296417Sdim  for (auto I = Stack.rbegin(), EE = Stack.rend(); I != EE; ++I)
764296417Sdim    if (I->CurScope == S)
765296417Sdim      return I->Directive;
766296417Sdim  return OMPD_unknown;
767296417Sdim}
768296417Sdim
769261991Sdimvoid Sema::InitDataSharingAttributesStack() {
770261991Sdim  VarDataSharingAttributesStack = new DSAStackTy(*this);
771261991Sdim}
772249261Sdim
773261991Sdim#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
774261991Sdim
775296417Sdimbool Sema::IsOpenMPCapturedByRef(VarDecl *VD,
776296417Sdim                                 const CapturedRegionScopeInfo *RSI) {
777296417Sdim  assert(LangOpts.OpenMP && "OpenMP is not allowed");
778296417Sdim
779296417Sdim  auto &Ctx = getASTContext();
780296417Sdim  bool IsByRef = true;
781296417Sdim
782296417Sdim  // Find the directive that is associated with the provided scope.
783296417Sdim  auto DKind = DSAStack->getDirectiveForScope(RSI->TheScope);
784296417Sdim  auto Ty = VD->getType();
785296417Sdim
786296417Sdim  if (isOpenMPTargetDirective(DKind)) {
787296417Sdim    // This table summarizes how a given variable should be passed to the device
788296417Sdim    // given its type and the clauses where it appears. This table is based on
789296417Sdim    // the description in OpenMP 4.5 [2.10.4, target Construct] and
790296417Sdim    // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
791296417Sdim    //
792296417Sdim    // =========================================================================
793296417Sdim    // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
794296417Sdim    // |      |(tofrom:scalar)|     |  pvt  |               |          |       |
795296417Sdim    // =========================================================================
796296417Sdim    // | scl  |               |     |       |       -       |          | bycopy|
797296417Sdim    // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
798296417Sdim    // | scl  |               |  x  |   -   |       -       |     -    | null  |
799296417Sdim    // | scl  |       x       |     |       |       -       |          | byref |
800296417Sdim    // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
801296417Sdim    // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
802296417Sdim    // | scl  |               |  -  |   -   |       -       |     x    | byref |
803296417Sdim    // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
804296417Sdim    //
805296417Sdim    // | agg  |      n.a.     |     |       |       -       |          | byref |
806296417Sdim    // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
807296417Sdim    // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
808296417Sdim    // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
809296417Sdim    // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
810296417Sdim    //
811296417Sdim    // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
812296417Sdim    // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
813296417Sdim    // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
814296417Sdim    // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
815296417Sdim    // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
816296417Sdim    // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
817296417Sdim    // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
818296417Sdim    // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
819296417Sdim    // =========================================================================
820296417Sdim    // Legend:
821296417Sdim    //  scl - scalar
822296417Sdim    //  ptr - pointer
823296417Sdim    //  agg - aggregate
824296417Sdim    //  x - applies
825296417Sdim    //  - - invalid in this combination
826296417Sdim    //  [] - mapped with an array section
827296417Sdim    //  byref - should be mapped by reference
828296417Sdim    //  byval - should be mapped by value
829296417Sdim    //  null - initialize a local variable to null on the device
830296417Sdim    //
831296417Sdim    // Observations:
832296417Sdim    //  - All scalar declarations that show up in a map clause have to be passed
833296417Sdim    //    by reference, because they may have been mapped in the enclosing data
834296417Sdim    //    environment.
835296417Sdim    //  - If the scalar value does not fit the size of uintptr, it has to be
836296417Sdim    //    passed by reference, regardless the result in the table above.
837296417Sdim    //  - For pointers mapped by value that have either an implicit map or an
838296417Sdim    //    array section, the runtime library may pass the NULL value to the
839296417Sdim    //    device instead of the value passed to it by the compiler.
840296417Sdim
841296417Sdim    // FIXME: Right now, only implicit maps are implemented. Properly mapping
842296417Sdim    // values requires having the map, private, and firstprivate clauses SEMA
843296417Sdim    // and parsing in place, which we don't yet.
844296417Sdim
845296417Sdim    if (Ty->isReferenceType())
846296417Sdim      Ty = Ty->castAs<ReferenceType>()->getPointeeType();
847296417Sdim    IsByRef = !Ty->isScalarType();
848296417Sdim  }
849296417Sdim
850296417Sdim  // When passing data by value, we need to make sure it fits the uintptr size
851296417Sdim  // and alignment, because the runtime library only deals with uintptr types.
852296417Sdim  // If it does not fit the uintptr size, we need to pass the data by reference
853296417Sdim  // instead.
854296417Sdim  if (!IsByRef &&
855296417Sdim      (Ctx.getTypeSizeInChars(Ty) >
856296417Sdim           Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
857296417Sdim       Ctx.getDeclAlign(VD) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType())))
858296417Sdim    IsByRef = true;
859296417Sdim
860296417Sdim  return IsByRef;
861296417Sdim}
862296417Sdim
863280031Sdimbool Sema::IsOpenMPCapturedVar(VarDecl *VD) {
864280031Sdim  assert(LangOpts.OpenMP && "OpenMP is not allowed");
865288943Sdim  VD = VD->getCanonicalDecl();
866296417Sdim
867296417Sdim  // If we are attempting to capture a global variable in a directive with
868296417Sdim  // 'target' we return true so that this global is also mapped to the device.
869296417Sdim  //
870296417Sdim  // FIXME: If the declaration is enclosed in a 'declare target' directive,
871296417Sdim  // then it should not be captured. Therefore, an extra check has to be
872296417Sdim  // inserted here once support for 'declare target' is added.
873296417Sdim  //
874296417Sdim  if (!VD->hasLocalStorage()) {
875296417Sdim    if (DSAStack->getCurrentDirective() == OMPD_target &&
876296417Sdim        !DSAStack->isClauseParsingMode()) {
877296417Sdim      return true;
878296417Sdim    }
879296417Sdim    if (DSAStack->getCurScope() &&
880296417Sdim        DSAStack->hasDirective(
881296417Sdim            [](OpenMPDirectiveKind K, const DeclarationNameInfo &DNI,
882296417Sdim               SourceLocation Loc) -> bool {
883296417Sdim              return isOpenMPTargetDirective(K);
884296417Sdim            },
885296417Sdim            false)) {
886296417Sdim      return true;
887296417Sdim    }
888296417Sdim  }
889296417Sdim
890288943Sdim  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
891288943Sdim      (!DSAStack->isClauseParsingMode() ||
892288943Sdim       DSAStack->getParentDirective() != OMPD_unknown)) {
893288943Sdim    if (DSAStack->isLoopControlVariable(VD) ||
894288943Sdim        (VD->hasLocalStorage() &&
895288943Sdim         isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
896288943Sdim        DSAStack->isForceVarCapturing())
897288943Sdim      return true;
898288943Sdim    auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isClauseParsingMode());
899280031Sdim    if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
900280031Sdim      return true;
901280031Sdim    DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(),
902288943Sdim                                   DSAStack->isClauseParsingMode());
903280031Sdim    return DVarPrivate.CKind != OMPC_unknown;
904280031Sdim  }
905280031Sdim  return false;
906280031Sdim}
907280031Sdim
908288943Sdimbool Sema::isOpenMPPrivateVar(VarDecl *VD, unsigned Level) {
909288943Sdim  assert(LangOpts.OpenMP && "OpenMP is not allowed");
910288943Sdim  return DSAStack->hasExplicitDSA(
911288943Sdim      VD, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level);
912288943Sdim}
913288943Sdim
914296417Sdimbool Sema::isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level) {
915296417Sdim  assert(LangOpts.OpenMP && "OpenMP is not allowed");
916296417Sdim  // Return true if the current level is no longer enclosed in a target region.
917296417Sdim
918296417Sdim  return !VD->hasLocalStorage() &&
919296417Sdim         DSAStack->hasExplicitDirective(isOpenMPTargetDirective, Level);
920296417Sdim}
921296417Sdim
922276479Sdimvoid Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
923261991Sdim
924261991Sdimvoid Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
925261991Sdim                               const DeclarationNameInfo &DirName,
926276479Sdim                               Scope *CurScope, SourceLocation Loc) {
927276479Sdim  DSAStack->push(DKind, DirName, CurScope, Loc);
928261991Sdim  PushExpressionEvaluationContext(PotentiallyEvaluated);
929261991Sdim}
930261991Sdim
931288943Sdimvoid Sema::StartOpenMPClause(OpenMPClauseKind K) {
932288943Sdim  DSAStack->setClauseParsingMode(K);
933288943Sdim}
934288943Sdim
935288943Sdimvoid Sema::EndOpenMPClause() {
936288943Sdim  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
937288943Sdim}
938288943Sdim
939261991Sdimvoid Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
940276479Sdim  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
941276479Sdim  //  A variable of class type (or array thereof) that appears in a lastprivate
942276479Sdim  //  clause requires an accessible, unambiguous default constructor for the
943276479Sdim  //  class type, unless the list item is also specified in a firstprivate
944276479Sdim  //  clause.
945276479Sdim  if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
946288943Sdim    for (auto *C : D->clauses()) {
947288943Sdim      if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
948288943Sdim        SmallVector<Expr *, 8> PrivateCopies;
949288943Sdim        for (auto *DE : Clause->varlists()) {
950288943Sdim          if (DE->isValueDependent() || DE->isTypeDependent()) {
951288943Sdim            PrivateCopies.push_back(nullptr);
952276479Sdim            continue;
953288943Sdim          }
954288943Sdim          auto *VD = cast<VarDecl>(cast<DeclRefExpr>(DE)->getDecl());
955296417Sdim          QualType Type = VD->getType().getNonReferenceType();
956276479Sdim          auto DVar = DSAStack->getTopDSA(VD, false);
957276479Sdim          if (DVar.CKind == OMPC_lastprivate) {
958288943Sdim            // Generate helper private variable and initialize it with the
959288943Sdim            // default value. The address of the original variable is replaced
960288943Sdim            // by the address of the new private variable in CodeGen. This new
961288943Sdim            // variable is not added to IdResolver, so the code in the OpenMP
962288943Sdim            // region uses original variable for proper diagnostics.
963296417Sdim            auto *VDPrivate = buildVarDecl(
964296417Sdim                *this, DE->getExprLoc(), Type.getUnqualifiedType(),
965296417Sdim                VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
966288943Sdim            ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
967288943Sdim            if (VDPrivate->isInvalidDecl())
968288943Sdim              continue;
969288943Sdim            PrivateCopies.push_back(buildDeclRefExpr(
970288943Sdim                *this, VDPrivate, DE->getType(), DE->getExprLoc()));
971288943Sdim          } else {
972288943Sdim            // The variable is also a firstprivate, so initialization sequence
973288943Sdim            // for private copy is generated already.
974288943Sdim            PrivateCopies.push_back(nullptr);
975276479Sdim          }
976276479Sdim        }
977288943Sdim        // Set initializers to private copies if no errors were found.
978288943Sdim        if (PrivateCopies.size() == Clause->varlist_size()) {
979288943Sdim          Clause->setPrivateCopies(PrivateCopies);
980288943Sdim        }
981276479Sdim      }
982276479Sdim    }
983276479Sdim  }
984276479Sdim
985261991Sdim  DSAStack->pop();
986261991Sdim  DiscardCleanupsInEvaluationContext();
987261991Sdim  PopExpressionEvaluationContext();
988261991Sdim}
989261991Sdim
990288943Sdimstatic bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
991288943Sdim                                     Expr *NumIterations, Sema &SemaRef,
992288943Sdim                                     Scope *S);
993288943Sdim
994261991Sdimnamespace {
995261991Sdim
996261991Sdimclass VarDeclFilterCCC : public CorrectionCandidateCallback {
997261991Sdimprivate:
998276479Sdim  Sema &SemaRef;
999276479Sdim
1000261991Sdimpublic:
1001276479Sdim  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1002276479Sdim  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1003261991Sdim    NamedDecl *ND = Candidate.getCorrectionDecl();
1004261991Sdim    if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
1005261991Sdim      return VD->hasGlobalStorage() &&
1006276479Sdim             SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1007276479Sdim                                   SemaRef.getCurScope());
1008261991Sdim    }
1009261991Sdim    return false;
1010261991Sdim  }
1011261991Sdim};
1012276479Sdim} // namespace
1013261991Sdim
1014261991SdimExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
1015261991Sdim                                         CXXScopeSpec &ScopeSpec,
1016261991Sdim                                         const DeclarationNameInfo &Id) {
1017261991Sdim  LookupResult Lookup(*this, Id, LookupOrdinaryName);
1018261991Sdim  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1019261991Sdim
1020261991Sdim  if (Lookup.isAmbiguous())
1021261991Sdim    return ExprError();
1022261991Sdim
1023261991Sdim  VarDecl *VD;
1024261991Sdim  if (!Lookup.isSingleResult()) {
1025280031Sdim    if (TypoCorrection Corrected = CorrectTypo(
1026280031Sdim            Id, LookupOrdinaryName, CurScope, nullptr,
1027280031Sdim            llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1028261991Sdim      diagnoseTypo(Corrected,
1029276479Sdim                   PDiag(Lookup.empty()
1030276479Sdim                             ? diag::err_undeclared_var_use_suggest
1031276479Sdim                             : diag::err_omp_expected_var_arg_suggest)
1032276479Sdim                       << Id.getName());
1033249261Sdim      VD = Corrected.getCorrectionDeclAs<VarDecl>();
1034249261Sdim    } else {
1035261991Sdim      Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1036261991Sdim                                       : diag::err_omp_expected_var_arg)
1037261991Sdim          << Id.getName();
1038261991Sdim      return ExprError();
1039249261Sdim    }
1040261991Sdim  } else {
1041261991Sdim    if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1042276479Sdim      Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1043261991Sdim      Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1044261991Sdim      return ExprError();
1045249261Sdim    }
1046261991Sdim  }
1047261991Sdim  Lookup.suppressDiagnostics();
1048249261Sdim
1049261991Sdim  // OpenMP [2.9.2, Syntax, C/C++]
1050261991Sdim  //   Variables must be file-scope, namespace-scope, or static block-scope.
1051261991Sdim  if (!VD->hasGlobalStorage()) {
1052261991Sdim    Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1053276479Sdim        << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1054276479Sdim    bool IsDecl =
1055276479Sdim        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1056261991Sdim    Diag(VD->getLocation(),
1057276479Sdim         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1058276479Sdim        << VD;
1059261991Sdim    return ExprError();
1060261991Sdim  }
1061249261Sdim
1062261991Sdim  VarDecl *CanonicalVD = VD->getCanonicalDecl();
1063261991Sdim  NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1064261991Sdim  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1065261991Sdim  //   A threadprivate directive for file-scope variables must appear outside
1066261991Sdim  //   any definition or declaration.
1067261991Sdim  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1068261991Sdim      !getCurLexicalContext()->isTranslationUnit()) {
1069261991Sdim    Diag(Id.getLoc(), diag::err_omp_var_scope)
1070276479Sdim        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1071276479Sdim    bool IsDecl =
1072276479Sdim        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1073276479Sdim    Diag(VD->getLocation(),
1074276479Sdim         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1075276479Sdim        << VD;
1076261991Sdim    return ExprError();
1077261991Sdim  }
1078261991Sdim  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1079261991Sdim  //   A threadprivate directive for static class member variables must appear
1080261991Sdim  //   in the class definition, in the same scope in which the member
1081261991Sdim  //   variables are declared.
1082261991Sdim  if (CanonicalVD->isStaticDataMember() &&
1083261991Sdim      !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1084261991Sdim    Diag(Id.getLoc(), diag::err_omp_var_scope)
1085276479Sdim        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1086276479Sdim    bool IsDecl =
1087276479Sdim        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1088276479Sdim    Diag(VD->getLocation(),
1089276479Sdim         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1090276479Sdim        << VD;
1091261991Sdim    return ExprError();
1092261991Sdim  }
1093261991Sdim  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1094261991Sdim  //   A threadprivate directive for namespace-scope variables must appear
1095261991Sdim  //   outside any definition or declaration other than the namespace
1096261991Sdim  //   definition itself.
1097261991Sdim  if (CanonicalVD->getDeclContext()->isNamespace() &&
1098261991Sdim      (!getCurLexicalContext()->isFileContext() ||
1099261991Sdim       !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1100261991Sdim    Diag(Id.getLoc(), diag::err_omp_var_scope)
1101276479Sdim        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1102276479Sdim    bool IsDecl =
1103276479Sdim        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1104276479Sdim    Diag(VD->getLocation(),
1105276479Sdim         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1106276479Sdim        << VD;
1107261991Sdim    return ExprError();
1108261991Sdim  }
1109261991Sdim  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1110261991Sdim  //   A threadprivate directive for static block-scope variables must appear
1111261991Sdim  //   in the scope of the variable and not in a nested scope.
1112261991Sdim  if (CanonicalVD->isStaticLocal() && CurScope &&
1113261991Sdim      !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1114261991Sdim    Diag(Id.getLoc(), diag::err_omp_var_scope)
1115276479Sdim        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1116276479Sdim    bool IsDecl =
1117276479Sdim        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1118276479Sdim    Diag(VD->getLocation(),
1119276479Sdim         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1120276479Sdim        << VD;
1121261991Sdim    return ExprError();
1122261991Sdim  }
1123249261Sdim
1124261991Sdim  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1125261991Sdim  //   A threadprivate directive must lexically precede all references to any
1126261991Sdim  //   of the variables in its list.
1127288943Sdim  if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1128261991Sdim    Diag(Id.getLoc(), diag::err_omp_var_used)
1129276479Sdim        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1130261991Sdim    return ExprError();
1131249261Sdim  }
1132261991Sdim
1133261991Sdim  QualType ExprType = VD->getType().getNonReferenceType();
1134288943Sdim  ExprResult DE = buildDeclRefExpr(*this, VD, ExprType, Id.getLoc());
1135261991Sdim  return DE;
1136261991Sdim}
1137261991Sdim
1138276479SdimSema::DeclGroupPtrTy
1139276479SdimSema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
1140276479Sdim                                        ArrayRef<Expr *> VarList) {
1141261991Sdim  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1142249261Sdim    CurContext->addDecl(D);
1143249261Sdim    return DeclGroupPtrTy::make(DeclGroupRef(D));
1144249261Sdim  }
1145249261Sdim  return DeclGroupPtrTy();
1146249261Sdim}
1147249261Sdim
1148276479Sdimnamespace {
1149276479Sdimclass LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1150276479Sdim  Sema &SemaRef;
1151276479Sdim
1152276479Sdimpublic:
1153276479Sdim  bool VisitDeclRefExpr(const DeclRefExpr *E) {
1154276479Sdim    if (auto VD = dyn_cast<VarDecl>(E->getDecl())) {
1155276479Sdim      if (VD->hasLocalStorage()) {
1156276479Sdim        SemaRef.Diag(E->getLocStart(),
1157276479Sdim                     diag::err_omp_local_var_in_threadprivate_init)
1158276479Sdim            << E->getSourceRange();
1159276479Sdim        SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1160276479Sdim            << VD << VD->getSourceRange();
1161276479Sdim        return true;
1162276479Sdim      }
1163276479Sdim    }
1164276479Sdim    return false;
1165276479Sdim  }
1166276479Sdim  bool VisitStmt(const Stmt *S) {
1167276479Sdim    for (auto Child : S->children()) {
1168276479Sdim      if (Child && Visit(Child))
1169276479Sdim        return true;
1170276479Sdim    }
1171276479Sdim    return false;
1172276479Sdim  }
1173276479Sdim  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1174276479Sdim};
1175276479Sdim} // namespace
1176276479Sdim
1177276479SdimOMPThreadPrivateDecl *
1178276479SdimSema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
1179261991Sdim  SmallVector<Expr *, 8> Vars;
1180276479Sdim  for (auto &RefExpr : VarList) {
1181276479Sdim    DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
1182261991Sdim    VarDecl *VD = cast<VarDecl>(DE->getDecl());
1183261991Sdim    SourceLocation ILoc = DE->getExprLoc();
1184249261Sdim
1185288943Sdim    QualType QType = VD->getType();
1186288943Sdim    if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1187288943Sdim      // It will be analyzed later.
1188288943Sdim      Vars.push_back(DE);
1189288943Sdim      continue;
1190288943Sdim    }
1191288943Sdim
1192249261Sdim    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1193249261Sdim    //   A threadprivate variable must not have an incomplete type.
1194249261Sdim    if (RequireCompleteType(ILoc, VD->getType(),
1195261991Sdim                            diag::err_omp_threadprivate_incomplete_type)) {
1196249261Sdim      continue;
1197249261Sdim    }
1198249261Sdim
1199249261Sdim    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1200249261Sdim    //   A threadprivate variable must not have a reference type.
1201249261Sdim    if (VD->getType()->isReferenceType()) {
1202249261Sdim      Diag(ILoc, diag::err_omp_ref_type_arg)
1203276479Sdim          << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1204276479Sdim      bool IsDecl =
1205276479Sdim          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1206276479Sdim      Diag(VD->getLocation(),
1207276479Sdim           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1208276479Sdim          << VD;
1209249261Sdim      continue;
1210249261Sdim    }
1211249261Sdim
1212288943Sdim    // Check if this is a TLS variable. If TLS is not being supported, produce
1213288943Sdim    // the corresponding diagnostic.
1214288943Sdim    if ((VD->getTLSKind() != VarDecl::TLS_None &&
1215288943Sdim         !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1216288943Sdim           getLangOpts().OpenMPUseTLS &&
1217288943Sdim           getASTContext().getTargetInfo().isTLSSupported())) ||
1218288943Sdim        (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1219288943Sdim         !VD->isLocalVarDecl())) {
1220280031Sdim      Diag(ILoc, diag::err_omp_var_thread_local)
1221280031Sdim          << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1222276479Sdim      bool IsDecl =
1223276479Sdim          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1224276479Sdim      Diag(VD->getLocation(),
1225276479Sdim           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1226276479Sdim          << VD;
1227249261Sdim      continue;
1228249261Sdim    }
1229249261Sdim
1230276479Sdim    // Check if initial value of threadprivate variable reference variable with
1231276479Sdim    // local storage (it is not supported by runtime).
1232276479Sdim    if (auto Init = VD->getAnyInitializer()) {
1233276479Sdim      LocalVarRefChecker Checker(*this);
1234276479Sdim      if (Checker.Visit(Init))
1235276479Sdim        continue;
1236276479Sdim    }
1237276479Sdim
1238276479Sdim    Vars.push_back(RefExpr);
1239276479Sdim    DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1240280031Sdim    VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1241280031Sdim        Context, SourceRange(Loc, Loc)));
1242280031Sdim    if (auto *ML = Context.getASTMutationListener())
1243280031Sdim      ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1244249261Sdim  }
1245276479Sdim  OMPThreadPrivateDecl *D = nullptr;
1246276479Sdim  if (!Vars.empty()) {
1247276479Sdim    D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1248276479Sdim                                     Vars);
1249276479Sdim    D->setAccess(AS_public);
1250276479Sdim  }
1251276479Sdim  return D;
1252249261Sdim}
1253261991Sdim
1254276479Sdimstatic void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1255276479Sdim                              const VarDecl *VD, DSAStackTy::DSAVarData DVar,
1256276479Sdim                              bool IsLoopIterVar = false) {
1257276479Sdim  if (DVar.RefExpr) {
1258276479Sdim    SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1259276479Sdim        << getOpenMPClauseName(DVar.CKind);
1260276479Sdim    return;
1261276479Sdim  }
1262276479Sdim  enum {
1263276479Sdim    PDSA_StaticMemberShared,
1264276479Sdim    PDSA_StaticLocalVarShared,
1265276479Sdim    PDSA_LoopIterVarPrivate,
1266276479Sdim    PDSA_LoopIterVarLinear,
1267276479Sdim    PDSA_LoopIterVarLastprivate,
1268276479Sdim    PDSA_ConstVarShared,
1269276479Sdim    PDSA_GlobalVarShared,
1270276479Sdim    PDSA_TaskVarFirstprivate,
1271276479Sdim    PDSA_LocalVarPrivate,
1272276479Sdim    PDSA_Implicit
1273276479Sdim  } Reason = PDSA_Implicit;
1274276479Sdim  bool ReportHint = false;
1275276479Sdim  auto ReportLoc = VD->getLocation();
1276276479Sdim  if (IsLoopIterVar) {
1277276479Sdim    if (DVar.CKind == OMPC_private)
1278276479Sdim      Reason = PDSA_LoopIterVarPrivate;
1279276479Sdim    else if (DVar.CKind == OMPC_lastprivate)
1280276479Sdim      Reason = PDSA_LoopIterVarLastprivate;
1281276479Sdim    else
1282276479Sdim      Reason = PDSA_LoopIterVarLinear;
1283276479Sdim  } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) {
1284276479Sdim    Reason = PDSA_TaskVarFirstprivate;
1285276479Sdim    ReportLoc = DVar.ImplicitDSALoc;
1286276479Sdim  } else if (VD->isStaticLocal())
1287276479Sdim    Reason = PDSA_StaticLocalVarShared;
1288276479Sdim  else if (VD->isStaticDataMember())
1289276479Sdim    Reason = PDSA_StaticMemberShared;
1290276479Sdim  else if (VD->isFileVarDecl())
1291276479Sdim    Reason = PDSA_GlobalVarShared;
1292276479Sdim  else if (VD->getType().isConstant(SemaRef.getASTContext()))
1293276479Sdim    Reason = PDSA_ConstVarShared;
1294276479Sdim  else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1295276479Sdim    ReportHint = true;
1296276479Sdim    Reason = PDSA_LocalVarPrivate;
1297276479Sdim  }
1298276479Sdim  if (Reason != PDSA_Implicit) {
1299276479Sdim    SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1300276479Sdim        << Reason << ReportHint
1301276479Sdim        << getOpenMPDirectiveName(Stack->getCurrentDirective());
1302276479Sdim  } else if (DVar.ImplicitDSALoc.isValid()) {
1303276479Sdim    SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1304276479Sdim        << getOpenMPClauseName(DVar.CKind);
1305276479Sdim  }
1306276479Sdim}
1307276479Sdim
1308261991Sdimnamespace {
1309261991Sdimclass DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1310261991Sdim  DSAStackTy *Stack;
1311276479Sdim  Sema &SemaRef;
1312261991Sdim  bool ErrorFound;
1313261991Sdim  CapturedStmt *CS;
1314261991Sdim  llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1315276479Sdim  llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
1316276479Sdim
1317261991Sdimpublic:
1318261991Sdim  void VisitDeclRefExpr(DeclRefExpr *E) {
1319276479Sdim    if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1320261991Sdim      // Skip internally declared variables.
1321276479Sdim      if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
1322276479Sdim        return;
1323261991Sdim
1324276479Sdim      auto DVar = Stack->getTopDSA(VD, false);
1325276479Sdim      // Check if the variable has explicit DSA set and stop analysis if it so.
1326276479Sdim      if (DVar.RefExpr) return;
1327261991Sdim
1328276479Sdim      auto ELoc = E->getExprLoc();
1329276479Sdim      auto DKind = Stack->getCurrentDirective();
1330261991Sdim      // The default(none) clause requires that each variable that is referenced
1331261991Sdim      // in the construct, and does not have a predetermined data-sharing
1332261991Sdim      // attribute, must have its data-sharing attribute explicitly determined
1333261991Sdim      // by being listed in a data-sharing attribute clause.
1334261991Sdim      if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1335276479Sdim          isParallelOrTaskRegion(DKind) &&
1336276479Sdim          VarsWithInheritedDSA.count(VD) == 0) {
1337276479Sdim        VarsWithInheritedDSA[VD] = E;
1338261991Sdim        return;
1339261991Sdim      }
1340261991Sdim
1341261991Sdim      // OpenMP [2.9.3.6, Restrictions, p.2]
1342261991Sdim      //  A list item that appears in a reduction clause of the innermost
1343261991Sdim      //  enclosing worksharing or parallel construct may not be accessed in an
1344261991Sdim      //  explicit task.
1345276479Sdim      DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
1346276479Sdim                                    [](OpenMPDirectiveKind K) -> bool {
1347276479Sdim                                      return isOpenMPParallelDirective(K) ||
1348280031Sdim                                             isOpenMPWorksharingDirective(K) ||
1349280031Sdim                                             isOpenMPTeamsDirective(K);
1350276479Sdim                                    },
1351276479Sdim                                    false);
1352276479Sdim      if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) {
1353276479Sdim        ErrorFound = true;
1354276479Sdim        SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1355276479Sdim        ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1356276479Sdim        return;
1357276479Sdim      }
1358261991Sdim
1359261991Sdim      // Define implicit data-sharing attributes for task.
1360276479Sdim      DVar = Stack->getImplicitDSA(VD, false);
1361261991Sdim      if (DKind == OMPD_task && DVar.CKind != OMPC_shared)
1362276479Sdim        ImplicitFirstprivate.push_back(E);
1363261991Sdim    }
1364261991Sdim  }
1365261991Sdim  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
1366276479Sdim    for (auto *C : S->clauses()) {
1367276479Sdim      // Skip analysis of arguments of implicitly defined firstprivate clause
1368276479Sdim      // for task directives.
1369276479Sdim      if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid()))
1370276479Sdim        for (auto *CC : C->children()) {
1371276479Sdim          if (CC)
1372276479Sdim            Visit(CC);
1373276479Sdim        }
1374276479Sdim    }
1375261991Sdim  }
1376261991Sdim  void VisitStmt(Stmt *S) {
1377276479Sdim    for (auto *C : S->children()) {
1378276479Sdim      if (C && !isa<OMPExecutableDirective>(C))
1379276479Sdim        Visit(C);
1380261991Sdim    }
1381276479Sdim  }
1382261991Sdim
1383261991Sdim  bool isErrorFound() { return ErrorFound; }
1384261991Sdim  ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
1385276479Sdim  llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() {
1386276479Sdim    return VarsWithInheritedDSA;
1387276479Sdim  }
1388261991Sdim
1389276479Sdim  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
1390276479Sdim      : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
1391261991Sdim};
1392276479Sdim} // namespace
1393276479Sdim
1394276479Sdimvoid Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
1395276479Sdim  switch (DKind) {
1396276479Sdim  case OMPD_parallel: {
1397276479Sdim    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1398296417Sdim    QualType KmpInt32PtrTy =
1399296417Sdim        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1400276479Sdim    Sema::CapturedParamNameType Params[] = {
1401276479Sdim        std::make_pair(".global_tid.", KmpInt32PtrTy),
1402276479Sdim        std::make_pair(".bound_tid.", KmpInt32PtrTy),
1403276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1404276479Sdim    };
1405276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1406276479Sdim                             Params);
1407276479Sdim    break;
1408276479Sdim  }
1409276479Sdim  case OMPD_simd: {
1410276479Sdim    Sema::CapturedParamNameType Params[] = {
1411276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1412276479Sdim    };
1413276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1414276479Sdim                             Params);
1415276479Sdim    break;
1416276479Sdim  }
1417276479Sdim  case OMPD_for: {
1418276479Sdim    Sema::CapturedParamNameType Params[] = {
1419276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1420276479Sdim    };
1421276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1422276479Sdim                             Params);
1423276479Sdim    break;
1424276479Sdim  }
1425280031Sdim  case OMPD_for_simd: {
1426280031Sdim    Sema::CapturedParamNameType Params[] = {
1427280031Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1428280031Sdim    };
1429280031Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1430280031Sdim                             Params);
1431280031Sdim    break;
1432280031Sdim  }
1433276479Sdim  case OMPD_sections: {
1434276479Sdim    Sema::CapturedParamNameType Params[] = {
1435276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1436276479Sdim    };
1437276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1438276479Sdim                             Params);
1439276479Sdim    break;
1440276479Sdim  }
1441276479Sdim  case OMPD_section: {
1442276479Sdim    Sema::CapturedParamNameType Params[] = {
1443276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1444276479Sdim    };
1445276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1446276479Sdim                             Params);
1447276479Sdim    break;
1448276479Sdim  }
1449276479Sdim  case OMPD_single: {
1450276479Sdim    Sema::CapturedParamNameType Params[] = {
1451276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1452276479Sdim    };
1453276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1454276479Sdim                             Params);
1455276479Sdim    break;
1456276479Sdim  }
1457276479Sdim  case OMPD_master: {
1458276479Sdim    Sema::CapturedParamNameType Params[] = {
1459276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1460276479Sdim    };
1461276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1462276479Sdim                             Params);
1463276479Sdim    break;
1464276479Sdim  }
1465276479Sdim  case OMPD_critical: {
1466276479Sdim    Sema::CapturedParamNameType Params[] = {
1467276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1468276479Sdim    };
1469276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1470276479Sdim                             Params);
1471276479Sdim    break;
1472276479Sdim  }
1473276479Sdim  case OMPD_parallel_for: {
1474276479Sdim    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1475296417Sdim    QualType KmpInt32PtrTy =
1476296417Sdim        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1477276479Sdim    Sema::CapturedParamNameType Params[] = {
1478276479Sdim        std::make_pair(".global_tid.", KmpInt32PtrTy),
1479276479Sdim        std::make_pair(".bound_tid.", KmpInt32PtrTy),
1480276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1481276479Sdim    };
1482276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1483276479Sdim                             Params);
1484276479Sdim    break;
1485276479Sdim  }
1486280031Sdim  case OMPD_parallel_for_simd: {
1487280031Sdim    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1488296417Sdim    QualType KmpInt32PtrTy =
1489296417Sdim        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1490280031Sdim    Sema::CapturedParamNameType Params[] = {
1491280031Sdim        std::make_pair(".global_tid.", KmpInt32PtrTy),
1492280031Sdim        std::make_pair(".bound_tid.", KmpInt32PtrTy),
1493280031Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1494280031Sdim    };
1495280031Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1496280031Sdim                             Params);
1497280031Sdim    break;
1498280031Sdim  }
1499276479Sdim  case OMPD_parallel_sections: {
1500288943Sdim    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1501296417Sdim    QualType KmpInt32PtrTy =
1502296417Sdim        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1503276479Sdim    Sema::CapturedParamNameType Params[] = {
1504288943Sdim        std::make_pair(".global_tid.", KmpInt32PtrTy),
1505288943Sdim        std::make_pair(".bound_tid.", KmpInt32PtrTy),
1506276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1507276479Sdim    };
1508276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1509276479Sdim                             Params);
1510276479Sdim    break;
1511276479Sdim  }
1512276479Sdim  case OMPD_task: {
1513288943Sdim    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1514288943Sdim    QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
1515288943Sdim    FunctionProtoType::ExtProtoInfo EPI;
1516288943Sdim    EPI.Variadic = true;
1517288943Sdim    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
1518276479Sdim    Sema::CapturedParamNameType Params[] = {
1519288943Sdim        std::make_pair(".global_tid.", KmpInt32Ty),
1520288943Sdim        std::make_pair(".part_id.", KmpInt32Ty),
1521288943Sdim        std::make_pair(".privates.",
1522288943Sdim                       Context.VoidPtrTy.withConst().withRestrict()),
1523288943Sdim        std::make_pair(
1524288943Sdim            ".copy_fn.",
1525288943Sdim            Context.getPointerType(CopyFnType).withConst().withRestrict()),
1526276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1527276479Sdim    };
1528276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1529276479Sdim                             Params);
1530288943Sdim    // Mark this captured region as inlined, because we don't use outlined
1531288943Sdim    // function directly.
1532288943Sdim    getCurCapturedRegion()->TheCapturedDecl->addAttr(
1533288943Sdim        AlwaysInlineAttr::CreateImplicit(
1534288943Sdim            Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
1535276479Sdim    break;
1536276479Sdim  }
1537280031Sdim  case OMPD_ordered: {
1538276479Sdim    Sema::CapturedParamNameType Params[] = {
1539276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1540276479Sdim    };
1541276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1542276479Sdim                             Params);
1543276479Sdim    break;
1544276479Sdim  }
1545280031Sdim  case OMPD_atomic: {
1546276479Sdim    Sema::CapturedParamNameType Params[] = {
1547276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1548276479Sdim    };
1549276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1550276479Sdim                             Params);
1551276479Sdim    break;
1552276479Sdim  }
1553296417Sdim  case OMPD_target_data:
1554280031Sdim  case OMPD_target: {
1555276479Sdim    Sema::CapturedParamNameType Params[] = {
1556276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1557276479Sdim    };
1558276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1559276479Sdim                             Params);
1560276479Sdim    break;
1561276479Sdim  }
1562280031Sdim  case OMPD_teams: {
1563280031Sdim    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1564296417Sdim    QualType KmpInt32PtrTy =
1565296417Sdim        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1566276479Sdim    Sema::CapturedParamNameType Params[] = {
1567280031Sdim        std::make_pair(".global_tid.", KmpInt32PtrTy),
1568280031Sdim        std::make_pair(".bound_tid.", KmpInt32PtrTy),
1569276479Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1570276479Sdim    };
1571276479Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1572276479Sdim                             Params);
1573276479Sdim    break;
1574276479Sdim  }
1575288943Sdim  case OMPD_taskgroup: {
1576288943Sdim    Sema::CapturedParamNameType Params[] = {
1577288943Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1578288943Sdim    };
1579288943Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1580288943Sdim                             Params);
1581288943Sdim    break;
1582288943Sdim  }
1583296417Sdim  case OMPD_taskloop: {
1584296417Sdim    Sema::CapturedParamNameType Params[] = {
1585296417Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1586296417Sdim    };
1587296417Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1588296417Sdim                             Params);
1589296417Sdim    break;
1590296417Sdim  }
1591296417Sdim  case OMPD_taskloop_simd: {
1592296417Sdim    Sema::CapturedParamNameType Params[] = {
1593296417Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1594296417Sdim    };
1595296417Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1596296417Sdim                             Params);
1597296417Sdim    break;
1598296417Sdim  }
1599296417Sdim  case OMPD_distribute: {
1600296417Sdim    Sema::CapturedParamNameType Params[] = {
1601296417Sdim        std::make_pair(StringRef(), QualType()) // __context with shared vars
1602296417Sdim    };
1603296417Sdim    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1604296417Sdim                             Params);
1605296417Sdim    break;
1606296417Sdim  }
1607276479Sdim  case OMPD_threadprivate:
1608280031Sdim  case OMPD_taskyield:
1609280031Sdim  case OMPD_barrier:
1610280031Sdim  case OMPD_taskwait:
1611288943Sdim  case OMPD_cancellation_point:
1612288943Sdim  case OMPD_cancel:
1613280031Sdim  case OMPD_flush:
1614276479Sdim    llvm_unreachable("OpenMP Directive is not allowed");
1615276479Sdim  case OMPD_unknown:
1616276479Sdim    llvm_unreachable("Unknown OpenMP directive");
1617276479Sdim  }
1618261991Sdim}
1619261991Sdim
1620288943SdimStmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
1621288943Sdim                                      ArrayRef<OMPClause *> Clauses) {
1622288943Sdim  if (!S.isUsable()) {
1623288943Sdim    ActOnCapturedRegionError();
1624288943Sdim    return StmtError();
1625288943Sdim  }
1626296417Sdim
1627296417Sdim  OMPOrderedClause *OC = nullptr;
1628296417Sdim  OMPScheduleClause *SC = nullptr;
1629296417Sdim  SmallVector<OMPLinearClause *, 4> LCs;
1630288943Sdim  // This is required for proper codegen.
1631288943Sdim  for (auto *Clause : Clauses) {
1632288943Sdim    if (isOpenMPPrivate(Clause->getClauseKind()) ||
1633288943Sdim        Clause->getClauseKind() == OMPC_copyprivate ||
1634288943Sdim        (getLangOpts().OpenMPUseTLS &&
1635288943Sdim         getASTContext().getTargetInfo().isTLSSupported() &&
1636288943Sdim         Clause->getClauseKind() == OMPC_copyin)) {
1637288943Sdim      DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
1638288943Sdim      // Mark all variables in private list clauses as used in inner region.
1639288943Sdim      for (auto *VarRef : Clause->children()) {
1640288943Sdim        if (auto *E = cast_or_null<Expr>(VarRef)) {
1641288943Sdim          MarkDeclarationsReferencedInExpr(E);
1642288943Sdim        }
1643288943Sdim      }
1644288943Sdim      DSAStack->setForceVarCapturing(/*V=*/false);
1645288943Sdim    } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) &&
1646288943Sdim               Clause->getClauseKind() == OMPC_schedule) {
1647288943Sdim      // Mark all variables in private list clauses as used in inner region.
1648288943Sdim      // Required for proper codegen of combined directives.
1649288943Sdim      // TODO: add processing for other clauses.
1650288943Sdim      if (auto *E = cast_or_null<Expr>(
1651296417Sdim              cast<OMPScheduleClause>(Clause)->getHelperChunkSize()))
1652296417Sdim        MarkDeclarationsReferencedInExpr(E);
1653288943Sdim    }
1654296417Sdim    if (Clause->getClauseKind() == OMPC_schedule)
1655296417Sdim      SC = cast<OMPScheduleClause>(Clause);
1656296417Sdim    else if (Clause->getClauseKind() == OMPC_ordered)
1657296417Sdim      OC = cast<OMPOrderedClause>(Clause);
1658296417Sdim    else if (Clause->getClauseKind() == OMPC_linear)
1659296417Sdim      LCs.push_back(cast<OMPLinearClause>(Clause));
1660288943Sdim  }
1661296417Sdim  bool ErrorFound = false;
1662296417Sdim  // OpenMP, 2.7.1 Loop Construct, Restrictions
1663296417Sdim  // The nonmonotonic modifier cannot be specified if an ordered clause is
1664296417Sdim  // specified.
1665296417Sdim  if (SC &&
1666296417Sdim      (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
1667296417Sdim       SC->getSecondScheduleModifier() ==
1668296417Sdim           OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
1669296417Sdim      OC) {
1670296417Sdim    Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
1671296417Sdim             ? SC->getFirstScheduleModifierLoc()
1672296417Sdim             : SC->getSecondScheduleModifierLoc(),
1673296417Sdim         diag::err_omp_schedule_nonmonotonic_ordered)
1674296417Sdim        << SourceRange(OC->getLocStart(), OC->getLocEnd());
1675296417Sdim    ErrorFound = true;
1676296417Sdim  }
1677296417Sdim  if (!LCs.empty() && OC && OC->getNumForLoops()) {
1678296417Sdim    for (auto *C : LCs) {
1679296417Sdim      Diag(C->getLocStart(), diag::err_omp_linear_ordered)
1680296417Sdim          << SourceRange(OC->getLocStart(), OC->getLocEnd());
1681296417Sdim    }
1682296417Sdim    ErrorFound = true;
1683296417Sdim  }
1684296417Sdim  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
1685296417Sdim      isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
1686296417Sdim      OC->getNumForLoops()) {
1687296417Sdim    Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
1688296417Sdim        << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
1689296417Sdim    ErrorFound = true;
1690296417Sdim  }
1691296417Sdim  if (ErrorFound) {
1692296417Sdim    ActOnCapturedRegionError();
1693296417Sdim    return StmtError();
1694296417Sdim  }
1695288943Sdim  return ActOnCapturedRegionEnd(S.get());
1696288943Sdim}
1697288943Sdim
1698276479Sdimstatic bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
1699276479Sdim                                  OpenMPDirectiveKind CurrentRegion,
1700276479Sdim                                  const DeclarationNameInfo &CurrentName,
1701288943Sdim                                  OpenMPDirectiveKind CancelRegion,
1702276479Sdim                                  SourceLocation StartLoc) {
1703276479Sdim  // Allowed nesting of constructs
1704276479Sdim  // +------------------+-----------------+------------------------------------+
1705276479Sdim  // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)|
1706276479Sdim  // +------------------+-----------------+------------------------------------+
1707276479Sdim  // | parallel         | parallel        | *                                  |
1708276479Sdim  // | parallel         | for             | *                                  |
1709280031Sdim  // | parallel         | for simd        | *                                  |
1710276479Sdim  // | parallel         | master          | *                                  |
1711276479Sdim  // | parallel         | critical        | *                                  |
1712276479Sdim  // | parallel         | simd            | *                                  |
1713276479Sdim  // | parallel         | sections        | *                                  |
1714276479Sdim  // | parallel         | section         | +                                  |
1715276479Sdim  // | parallel         | single          | *                                  |
1716276479Sdim  // | parallel         | parallel for    | *                                  |
1717280031Sdim  // | parallel         |parallel for simd| *                                  |
1718276479Sdim  // | parallel         |parallel sections| *                                  |
1719276479Sdim  // | parallel         | task            | *                                  |
1720276479Sdim  // | parallel         | taskyield       | *                                  |
1721276479Sdim  // | parallel         | barrier         | *                                  |
1722276479Sdim  // | parallel         | taskwait        | *                                  |
1723288943Sdim  // | parallel         | taskgroup       | *                                  |
1724276479Sdim  // | parallel         | flush           | *                                  |
1725280031Sdim  // | parallel         | ordered         | +                                  |
1726280031Sdim  // | parallel         | atomic          | *                                  |
1727280031Sdim  // | parallel         | target          | *                                  |
1728280031Sdim  // | parallel         | teams           | +                                  |
1729288943Sdim  // | parallel         | cancellation    |                                    |
1730288943Sdim  // |                  | point           | !                                  |
1731288943Sdim  // | parallel         | cancel          | !                                  |
1732296417Sdim  // | parallel         | taskloop        | *                                  |
1733296417Sdim  // | parallel         | taskloop simd   | *                                  |
1734296417Sdim  // | parallel         | distribute      |                                    |
1735276479Sdim  // +------------------+-----------------+------------------------------------+
1736276479Sdim  // | for              | parallel        | *                                  |
1737276479Sdim  // | for              | for             | +                                  |
1738280031Sdim  // | for              | for simd        | +                                  |
1739276479Sdim  // | for              | master          | +                                  |
1740276479Sdim  // | for              | critical        | *                                  |
1741276479Sdim  // | for              | simd            | *                                  |
1742276479Sdim  // | for              | sections        | +                                  |
1743276479Sdim  // | for              | section         | +                                  |
1744276479Sdim  // | for              | single          | +                                  |
1745276479Sdim  // | for              | parallel for    | *                                  |
1746280031Sdim  // | for              |parallel for simd| *                                  |
1747276479Sdim  // | for              |parallel sections| *                                  |
1748276479Sdim  // | for              | task            | *                                  |
1749276479Sdim  // | for              | taskyield       | *                                  |
1750276479Sdim  // | for              | barrier         | +                                  |
1751276479Sdim  // | for              | taskwait        | *                                  |
1752288943Sdim  // | for              | taskgroup       | *                                  |
1753276479Sdim  // | for              | flush           | *                                  |
1754280031Sdim  // | for              | ordered         | * (if construct is ordered)        |
1755280031Sdim  // | for              | atomic          | *                                  |
1756280031Sdim  // | for              | target          | *                                  |
1757280031Sdim  // | for              | teams           | +                                  |
1758288943Sdim  // | for              | cancellation    |                                    |
1759288943Sdim  // |                  | point           | !                                  |
1760288943Sdim  // | for              | cancel          | !                                  |
1761296417Sdim  // | for              | taskloop        | *                                  |
1762296417Sdim  // | for              | taskloop simd   | *                                  |
1763296417Sdim  // | for              | distribute      |                                    |
1764276479Sdim  // +------------------+-----------------+------------------------------------+
1765276479Sdim  // | master           | parallel        | *                                  |
1766276479Sdim  // | master           | for             | +                                  |
1767280031Sdim  // | master           | for simd        | +                                  |
1768276479Sdim  // | master           | master          | *                                  |
1769276479Sdim  // | master           | critical        | *                                  |
1770276479Sdim  // | master           | simd            | *                                  |
1771276479Sdim  // | master           | sections        | +                                  |
1772276479Sdim  // | master           | section         | +                                  |
1773276479Sdim  // | master           | single          | +                                  |
1774276479Sdim  // | master           | parallel for    | *                                  |
1775280031Sdim  // | master           |parallel for simd| *                                  |
1776276479Sdim  // | master           |parallel sections| *                                  |
1777276479Sdim  // | master           | task            | *                                  |
1778276479Sdim  // | master           | taskyield       | *                                  |
1779276479Sdim  // | master           | barrier         | +                                  |
1780276479Sdim  // | master           | taskwait        | *                                  |
1781288943Sdim  // | master           | taskgroup       | *                                  |
1782276479Sdim  // | master           | flush           | *                                  |
1783280031Sdim  // | master           | ordered         | +                                  |
1784280031Sdim  // | master           | atomic          | *                                  |
1785280031Sdim  // | master           | target          | *                                  |
1786280031Sdim  // | master           | teams           | +                                  |
1787288943Sdim  // | master           | cancellation    |                                    |
1788288943Sdim  // |                  | point           |                                    |
1789288943Sdim  // | master           | cancel          |                                    |
1790296417Sdim  // | master           | taskloop        | *                                  |
1791296417Sdim  // | master           | taskloop simd   | *                                  |
1792296417Sdim  // | master           | distribute      |                                    |
1793276479Sdim  // +------------------+-----------------+------------------------------------+
1794276479Sdim  // | critical         | parallel        | *                                  |
1795276479Sdim  // | critical         | for             | +                                  |
1796280031Sdim  // | critical         | for simd        | +                                  |
1797276479Sdim  // | critical         | master          | *                                  |
1798280031Sdim  // | critical         | critical        | * (should have different names)    |
1799276479Sdim  // | critical         | simd            | *                                  |
1800276479Sdim  // | critical         | sections        | +                                  |
1801276479Sdim  // | critical         | section         | +                                  |
1802276479Sdim  // | critical         | single          | +                                  |
1803276479Sdim  // | critical         | parallel for    | *                                  |
1804280031Sdim  // | critical         |parallel for simd| *                                  |
1805276479Sdim  // | critical         |parallel sections| *                                  |
1806276479Sdim  // | critical         | task            | *                                  |
1807276479Sdim  // | critical         | taskyield       | *                                  |
1808276479Sdim  // | critical         | barrier         | +                                  |
1809276479Sdim  // | critical         | taskwait        | *                                  |
1810288943Sdim  // | critical         | taskgroup       | *                                  |
1811280031Sdim  // | critical         | ordered         | +                                  |
1812280031Sdim  // | critical         | atomic          | *                                  |
1813280031Sdim  // | critical         | target          | *                                  |
1814280031Sdim  // | critical         | teams           | +                                  |
1815288943Sdim  // | critical         | cancellation    |                                    |
1816288943Sdim  // |                  | point           |                                    |
1817288943Sdim  // | critical         | cancel          |                                    |
1818296417Sdim  // | critical         | taskloop        | *                                  |
1819296417Sdim  // | critical         | taskloop simd   | *                                  |
1820296417Sdim  // | critical         | distribute      |                                    |
1821276479Sdim  // +------------------+-----------------+------------------------------------+
1822276479Sdim  // | simd             | parallel        |                                    |
1823276479Sdim  // | simd             | for             |                                    |
1824280031Sdim  // | simd             | for simd        |                                    |
1825276479Sdim  // | simd             | master          |                                    |
1826276479Sdim  // | simd             | critical        |                                    |
1827276479Sdim  // | simd             | simd            |                                    |
1828276479Sdim  // | simd             | sections        |                                    |
1829276479Sdim  // | simd             | section         |                                    |
1830276479Sdim  // | simd             | single          |                                    |
1831276479Sdim  // | simd             | parallel for    |                                    |
1832280031Sdim  // | simd             |parallel for simd|                                    |
1833276479Sdim  // | simd             |parallel sections|                                    |
1834276479Sdim  // | simd             | task            |                                    |
1835276479Sdim  // | simd             | taskyield       |                                    |
1836276479Sdim  // | simd             | barrier         |                                    |
1837276479Sdim  // | simd             | taskwait        |                                    |
1838288943Sdim  // | simd             | taskgroup       |                                    |
1839276479Sdim  // | simd             | flush           |                                    |
1840296417Sdim  // | simd             | ordered         | + (with simd clause)               |
1841280031Sdim  // | simd             | atomic          |                                    |
1842280031Sdim  // | simd             | target          |                                    |
1843280031Sdim  // | simd             | teams           |                                    |
1844288943Sdim  // | simd             | cancellation    |                                    |
1845288943Sdim  // |                  | point           |                                    |
1846288943Sdim  // | simd             | cancel          |                                    |
1847296417Sdim  // | simd             | taskloop        |                                    |
1848296417Sdim  // | simd             | taskloop simd   |                                    |
1849296417Sdim  // | simd             | distribute      |                                    |
1850276479Sdim  // +------------------+-----------------+------------------------------------+
1851280031Sdim  // | for simd         | parallel        |                                    |
1852280031Sdim  // | for simd         | for             |                                    |
1853280031Sdim  // | for simd         | for simd        |                                    |
1854280031Sdim  // | for simd         | master          |                                    |
1855280031Sdim  // | for simd         | critical        |                                    |
1856280031Sdim  // | for simd         | simd            |                                    |
1857280031Sdim  // | for simd         | sections        |                                    |
1858280031Sdim  // | for simd         | section         |                                    |
1859280031Sdim  // | for simd         | single          |                                    |
1860280031Sdim  // | for simd         | parallel for    |                                    |
1861280031Sdim  // | for simd         |parallel for simd|                                    |
1862280031Sdim  // | for simd         |parallel sections|                                    |
1863280031Sdim  // | for simd         | task            |                                    |
1864280031Sdim  // | for simd         | taskyield       |                                    |
1865280031Sdim  // | for simd         | barrier         |                                    |
1866280031Sdim  // | for simd         | taskwait        |                                    |
1867288943Sdim  // | for simd         | taskgroup       |                                    |
1868280031Sdim  // | for simd         | flush           |                                    |
1869296417Sdim  // | for simd         | ordered         | + (with simd clause)               |
1870280031Sdim  // | for simd         | atomic          |                                    |
1871280031Sdim  // | for simd         | target          |                                    |
1872280031Sdim  // | for simd         | teams           |                                    |
1873288943Sdim  // | for simd         | cancellation    |                                    |
1874288943Sdim  // |                  | point           |                                    |
1875288943Sdim  // | for simd         | cancel          |                                    |
1876296417Sdim  // | for simd         | taskloop        |                                    |
1877296417Sdim  // | for simd         | taskloop simd   |                                    |
1878296417Sdim  // | for simd         | distribute      |                                    |
1879280031Sdim  // +------------------+-----------------+------------------------------------+
1880280031Sdim  // | parallel for simd| parallel        |                                    |
1881280031Sdim  // | parallel for simd| for             |                                    |
1882280031Sdim  // | parallel for simd| for simd        |                                    |
1883280031Sdim  // | parallel for simd| master          |                                    |
1884280031Sdim  // | parallel for simd| critical        |                                    |
1885280031Sdim  // | parallel for simd| simd            |                                    |
1886280031Sdim  // | parallel for simd| sections        |                                    |
1887280031Sdim  // | parallel for simd| section         |                                    |
1888280031Sdim  // | parallel for simd| single          |                                    |
1889280031Sdim  // | parallel for simd| parallel for    |                                    |
1890280031Sdim  // | parallel for simd|parallel for simd|                                    |
1891280031Sdim  // | parallel for simd|parallel sections|                                    |
1892280031Sdim  // | parallel for simd| task            |                                    |
1893280031Sdim  // | parallel for simd| taskyield       |                                    |
1894280031Sdim  // | parallel for simd| barrier         |                                    |
1895280031Sdim  // | parallel for simd| taskwait        |                                    |
1896288943Sdim  // | parallel for simd| taskgroup       |                                    |
1897280031Sdim  // | parallel for simd| flush           |                                    |
1898296417Sdim  // | parallel for simd| ordered         | + (with simd clause)               |
1899280031Sdim  // | parallel for simd| atomic          |                                    |
1900280031Sdim  // | parallel for simd| target          |                                    |
1901280031Sdim  // | parallel for simd| teams           |                                    |
1902288943Sdim  // | parallel for simd| cancellation    |                                    |
1903288943Sdim  // |                  | point           |                                    |
1904288943Sdim  // | parallel for simd| cancel          |                                    |
1905296417Sdim  // | parallel for simd| taskloop        |                                    |
1906296417Sdim  // | parallel for simd| taskloop simd   |                                    |
1907296417Sdim  // | parallel for simd| distribute      |                                    |
1908280031Sdim  // +------------------+-----------------+------------------------------------+
1909276479Sdim  // | sections         | parallel        | *                                  |
1910276479Sdim  // | sections         | for             | +                                  |
1911280031Sdim  // | sections         | for simd        | +                                  |
1912276479Sdim  // | sections         | master          | +                                  |
1913276479Sdim  // | sections         | critical        | *                                  |
1914276479Sdim  // | sections         | simd            | *                                  |
1915276479Sdim  // | sections         | sections        | +                                  |
1916276479Sdim  // | sections         | section         | *                                  |
1917276479Sdim  // | sections         | single          | +                                  |
1918276479Sdim  // | sections         | parallel for    | *                                  |
1919280031Sdim  // | sections         |parallel for simd| *                                  |
1920276479Sdim  // | sections         |parallel sections| *                                  |
1921276479Sdim  // | sections         | task            | *                                  |
1922276479Sdim  // | sections         | taskyield       | *                                  |
1923276479Sdim  // | sections         | barrier         | +                                  |
1924276479Sdim  // | sections         | taskwait        | *                                  |
1925288943Sdim  // | sections         | taskgroup       | *                                  |
1926276479Sdim  // | sections         | flush           | *                                  |
1927280031Sdim  // | sections         | ordered         | +                                  |
1928280031Sdim  // | sections         | atomic          | *                                  |
1929280031Sdim  // | sections         | target          | *                                  |
1930280031Sdim  // | sections         | teams           | +                                  |
1931288943Sdim  // | sections         | cancellation    |                                    |
1932288943Sdim  // |                  | point           | !                                  |
1933288943Sdim  // | sections         | cancel          | !                                  |
1934296417Sdim  // | sections         | taskloop        | *                                  |
1935296417Sdim  // | sections         | taskloop simd   | *                                  |
1936296417Sdim  // | sections         | distribute      |                                    |
1937276479Sdim  // +------------------+-----------------+------------------------------------+
1938276479Sdim  // | section          | parallel        | *                                  |
1939276479Sdim  // | section          | for             | +                                  |
1940280031Sdim  // | section          | for simd        | +                                  |
1941276479Sdim  // | section          | master          | +                                  |
1942276479Sdim  // | section          | critical        | *                                  |
1943276479Sdim  // | section          | simd            | *                                  |
1944276479Sdim  // | section          | sections        | +                                  |
1945276479Sdim  // | section          | section         | +                                  |
1946276479Sdim  // | section          | single          | +                                  |
1947276479Sdim  // | section          | parallel for    | *                                  |
1948280031Sdim  // | section          |parallel for simd| *                                  |
1949276479Sdim  // | section          |parallel sections| *                                  |
1950276479Sdim  // | section          | task            | *                                  |
1951276479Sdim  // | section          | taskyield       | *                                  |
1952276479Sdim  // | section          | barrier         | +                                  |
1953276479Sdim  // | section          | taskwait        | *                                  |
1954288943Sdim  // | section          | taskgroup       | *                                  |
1955276479Sdim  // | section          | flush           | *                                  |
1956280031Sdim  // | section          | ordered         | +                                  |
1957280031Sdim  // | section          | atomic          | *                                  |
1958280031Sdim  // | section          | target          | *                                  |
1959280031Sdim  // | section          | teams           | +                                  |
1960288943Sdim  // | section          | cancellation    |                                    |
1961288943Sdim  // |                  | point           | !                                  |
1962288943Sdim  // | section          | cancel          | !                                  |
1963296417Sdim  // | section          | taskloop        | *                                  |
1964296417Sdim  // | section          | taskloop simd   | *                                  |
1965296417Sdim  // | section          | distribute      |                                    |
1966276479Sdim  // +------------------+-----------------+------------------------------------+
1967276479Sdim  // | single           | parallel        | *                                  |
1968276479Sdim  // | single           | for             | +                                  |
1969280031Sdim  // | single           | for simd        | +                                  |
1970276479Sdim  // | single           | master          | +                                  |
1971276479Sdim  // | single           | critical        | *                                  |
1972276479Sdim  // | single           | simd            | *                                  |
1973276479Sdim  // | single           | sections        | +                                  |
1974276479Sdim  // | single           | section         | +                                  |
1975276479Sdim  // | single           | single          | +                                  |
1976276479Sdim  // | single           | parallel for    | *                                  |
1977280031Sdim  // | single           |parallel for simd| *                                  |
1978276479Sdim  // | single           |parallel sections| *                                  |
1979276479Sdim  // | single           | task            | *                                  |
1980276479Sdim  // | single           | taskyield       | *                                  |
1981276479Sdim  // | single           | barrier         | +                                  |
1982276479Sdim  // | single           | taskwait        | *                                  |
1983288943Sdim  // | single           | taskgroup       | *                                  |
1984276479Sdim  // | single           | flush           | *                                  |
1985280031Sdim  // | single           | ordered         | +                                  |
1986280031Sdim  // | single           | atomic          | *                                  |
1987280031Sdim  // | single           | target          | *                                  |
1988280031Sdim  // | single           | teams           | +                                  |
1989288943Sdim  // | single           | cancellation    |                                    |
1990288943Sdim  // |                  | point           |                                    |
1991288943Sdim  // | single           | cancel          |                                    |
1992296417Sdim  // | single           | taskloop        | *                                  |
1993296417Sdim  // | single           | taskloop simd   | *                                  |
1994296417Sdim  // | single           | distribute      |                                    |
1995276479Sdim  // +------------------+-----------------+------------------------------------+
1996276479Sdim  // | parallel for     | parallel        | *                                  |
1997276479Sdim  // | parallel for     | for             | +                                  |
1998280031Sdim  // | parallel for     | for simd        | +                                  |
1999276479Sdim  // | parallel for     | master          | +                                  |
2000276479Sdim  // | parallel for     | critical        | *                                  |
2001276479Sdim  // | parallel for     | simd            | *                                  |
2002276479Sdim  // | parallel for     | sections        | +                                  |
2003276479Sdim  // | parallel for     | section         | +                                  |
2004276479Sdim  // | parallel for     | single          | +                                  |
2005276479Sdim  // | parallel for     | parallel for    | *                                  |
2006280031Sdim  // | parallel for     |parallel for simd| *                                  |
2007276479Sdim  // | parallel for     |parallel sections| *                                  |
2008276479Sdim  // | parallel for     | task            | *                                  |
2009276479Sdim  // | parallel for     | taskyield       | *                                  |
2010276479Sdim  // | parallel for     | barrier         | +                                  |
2011276479Sdim  // | parallel for     | taskwait        | *                                  |
2012288943Sdim  // | parallel for     | taskgroup       | *                                  |
2013276479Sdim  // | parallel for     | flush           | *                                  |
2014280031Sdim  // | parallel for     | ordered         | * (if construct is ordered)        |
2015280031Sdim  // | parallel for     | atomic          | *                                  |
2016280031Sdim  // | parallel for     | target          | *                                  |
2017280031Sdim  // | parallel for     | teams           | +                                  |
2018288943Sdim  // | parallel for     | cancellation    |                                    |
2019288943Sdim  // |                  | point           | !                                  |
2020288943Sdim  // | parallel for     | cancel          | !                                  |
2021296417Sdim  // | parallel for     | taskloop        | *                                  |
2022296417Sdim  // | parallel for     | taskloop simd   | *                                  |
2023296417Sdim  // | parallel for     | distribute      |                                    |
2024276479Sdim  // +------------------+-----------------+------------------------------------+
2025276479Sdim  // | parallel sections| parallel        | *                                  |
2026276479Sdim  // | parallel sections| for             | +                                  |
2027280031Sdim  // | parallel sections| for simd        | +                                  |
2028276479Sdim  // | parallel sections| master          | +                                  |
2029276479Sdim  // | parallel sections| critical        | +                                  |
2030276479Sdim  // | parallel sections| simd            | *                                  |
2031276479Sdim  // | parallel sections| sections        | +                                  |
2032276479Sdim  // | parallel sections| section         | *                                  |
2033276479Sdim  // | parallel sections| single          | +                                  |
2034276479Sdim  // | parallel sections| parallel for    | *                                  |
2035280031Sdim  // | parallel sections|parallel for simd| *                                  |
2036276479Sdim  // | parallel sections|parallel sections| *                                  |
2037276479Sdim  // | parallel sections| task            | *                                  |
2038276479Sdim  // | parallel sections| taskyield       | *                                  |
2039276479Sdim  // | parallel sections| barrier         | +                                  |
2040276479Sdim  // | parallel sections| taskwait        | *                                  |
2041288943Sdim  // | parallel sections| taskgroup       | *                                  |
2042276479Sdim  // | parallel sections| flush           | *                                  |
2043280031Sdim  // | parallel sections| ordered         | +                                  |
2044280031Sdim  // | parallel sections| atomic          | *                                  |
2045280031Sdim  // | parallel sections| target          | *                                  |
2046280031Sdim  // | parallel sections| teams           | +                                  |
2047288943Sdim  // | parallel sections| cancellation    |                                    |
2048288943Sdim  // |                  | point           | !                                  |
2049288943Sdim  // | parallel sections| cancel          | !                                  |
2050296417Sdim  // | parallel sections| taskloop        | *                                  |
2051296417Sdim  // | parallel sections| taskloop simd   | *                                  |
2052296417Sdim  // | parallel sections| distribute      |                                    |
2053276479Sdim  // +------------------+-----------------+------------------------------------+
2054276479Sdim  // | task             | parallel        | *                                  |
2055276479Sdim  // | task             | for             | +                                  |
2056280031Sdim  // | task             | for simd        | +                                  |
2057276479Sdim  // | task             | master          | +                                  |
2058276479Sdim  // | task             | critical        | *                                  |
2059276479Sdim  // | task             | simd            | *                                  |
2060276479Sdim  // | task             | sections        | +                                  |
2061276479Sdim  // | task             | section         | +                                  |
2062276479Sdim  // | task             | single          | +                                  |
2063276479Sdim  // | task             | parallel for    | *                                  |
2064280031Sdim  // | task             |parallel for simd| *                                  |
2065276479Sdim  // | task             |parallel sections| *                                  |
2066276479Sdim  // | task             | task            | *                                  |
2067276479Sdim  // | task             | taskyield       | *                                  |
2068276479Sdim  // | task             | barrier         | +                                  |
2069276479Sdim  // | task             | taskwait        | *                                  |
2070288943Sdim  // | task             | taskgroup       | *                                  |
2071276479Sdim  // | task             | flush           | *                                  |
2072280031Sdim  // | task             | ordered         | +                                  |
2073280031Sdim  // | task             | atomic          | *                                  |
2074280031Sdim  // | task             | target          | *                                  |
2075280031Sdim  // | task             | teams           | +                                  |
2076288943Sdim  // | task             | cancellation    |                                    |
2077288943Sdim  // |                  | point           | !                                  |
2078288943Sdim  // | task             | cancel          | !                                  |
2079296417Sdim  // | task             | taskloop        | *                                  |
2080296417Sdim  // | task             | taskloop simd   | *                                  |
2081296417Sdim  // | task             | distribute      |                                    |
2082276479Sdim  // +------------------+-----------------+------------------------------------+
2083280031Sdim  // | ordered          | parallel        | *                                  |
2084280031Sdim  // | ordered          | for             | +                                  |
2085280031Sdim  // | ordered          | for simd        | +                                  |
2086280031Sdim  // | ordered          | master          | *                                  |
2087280031Sdim  // | ordered          | critical        | *                                  |
2088280031Sdim  // | ordered          | simd            | *                                  |
2089280031Sdim  // | ordered          | sections        | +                                  |
2090280031Sdim  // | ordered          | section         | +                                  |
2091280031Sdim  // | ordered          | single          | +                                  |
2092280031Sdim  // | ordered          | parallel for    | *                                  |
2093280031Sdim  // | ordered          |parallel for simd| *                                  |
2094280031Sdim  // | ordered          |parallel sections| *                                  |
2095280031Sdim  // | ordered          | task            | *                                  |
2096280031Sdim  // | ordered          | taskyield       | *                                  |
2097280031Sdim  // | ordered          | barrier         | +                                  |
2098280031Sdim  // | ordered          | taskwait        | *                                  |
2099288943Sdim  // | ordered          | taskgroup       | *                                  |
2100280031Sdim  // | ordered          | flush           | *                                  |
2101280031Sdim  // | ordered          | ordered         | +                                  |
2102280031Sdim  // | ordered          | atomic          | *                                  |
2103280031Sdim  // | ordered          | target          | *                                  |
2104280031Sdim  // | ordered          | teams           | +                                  |
2105288943Sdim  // | ordered          | cancellation    |                                    |
2106288943Sdim  // |                  | point           |                                    |
2107288943Sdim  // | ordered          | cancel          |                                    |
2108296417Sdim  // | ordered          | taskloop        | *                                  |
2109296417Sdim  // | ordered          | taskloop simd   | *                                  |
2110296417Sdim  // | ordered          | distribute      |                                    |
2111280031Sdim  // +------------------+-----------------+------------------------------------+
2112280031Sdim  // | atomic           | parallel        |                                    |
2113280031Sdim  // | atomic           | for             |                                    |
2114280031Sdim  // | atomic           | for simd        |                                    |
2115280031Sdim  // | atomic           | master          |                                    |
2116280031Sdim  // | atomic           | critical        |                                    |
2117280031Sdim  // | atomic           | simd            |                                    |
2118280031Sdim  // | atomic           | sections        |                                    |
2119280031Sdim  // | atomic           | section         |                                    |
2120280031Sdim  // | atomic           | single          |                                    |
2121280031Sdim  // | atomic           | parallel for    |                                    |
2122280031Sdim  // | atomic           |parallel for simd|                                    |
2123280031Sdim  // | atomic           |parallel sections|                                    |
2124280031Sdim  // | atomic           | task            |                                    |
2125280031Sdim  // | atomic           | taskyield       |                                    |
2126280031Sdim  // | atomic           | barrier         |                                    |
2127280031Sdim  // | atomic           | taskwait        |                                    |
2128288943Sdim  // | atomic           | taskgroup       |                                    |
2129280031Sdim  // | atomic           | flush           |                                    |
2130280031Sdim  // | atomic           | ordered         |                                    |
2131280031Sdim  // | atomic           | atomic          |                                    |
2132280031Sdim  // | atomic           | target          |                                    |
2133280031Sdim  // | atomic           | teams           |                                    |
2134288943Sdim  // | atomic           | cancellation    |                                    |
2135288943Sdim  // |                  | point           |                                    |
2136288943Sdim  // | atomic           | cancel          |                                    |
2137296417Sdim  // | atomic           | taskloop        |                                    |
2138296417Sdim  // | atomic           | taskloop simd   |                                    |
2139296417Sdim  // | atomic           | distribute      |                                    |
2140280031Sdim  // +------------------+-----------------+------------------------------------+
2141280031Sdim  // | target           | parallel        | *                                  |
2142280031Sdim  // | target           | for             | *                                  |
2143280031Sdim  // | target           | for simd        | *                                  |
2144280031Sdim  // | target           | master          | *                                  |
2145280031Sdim  // | target           | critical        | *                                  |
2146280031Sdim  // | target           | simd            | *                                  |
2147280031Sdim  // | target           | sections        | *                                  |
2148280031Sdim  // | target           | section         | *                                  |
2149280031Sdim  // | target           | single          | *                                  |
2150280031Sdim  // | target           | parallel for    | *                                  |
2151280031Sdim  // | target           |parallel for simd| *                                  |
2152280031Sdim  // | target           |parallel sections| *                                  |
2153280031Sdim  // | target           | task            | *                                  |
2154280031Sdim  // | target           | taskyield       | *                                  |
2155280031Sdim  // | target           | barrier         | *                                  |
2156280031Sdim  // | target           | taskwait        | *                                  |
2157288943Sdim  // | target           | taskgroup       | *                                  |
2158280031Sdim  // | target           | flush           | *                                  |
2159280031Sdim  // | target           | ordered         | *                                  |
2160280031Sdim  // | target           | atomic          | *                                  |
2161280031Sdim  // | target           | target          | *                                  |
2162280031Sdim  // | target           | teams           | *                                  |
2163288943Sdim  // | target           | cancellation    |                                    |
2164288943Sdim  // |                  | point           |                                    |
2165288943Sdim  // | target           | cancel          |                                    |
2166296417Sdim  // | target           | taskloop        | *                                  |
2167296417Sdim  // | target           | taskloop simd   | *                                  |
2168296417Sdim  // | target           | distribute      |                                    |
2169280031Sdim  // +------------------+-----------------+------------------------------------+
2170280031Sdim  // | teams            | parallel        | *                                  |
2171280031Sdim  // | teams            | for             | +                                  |
2172280031Sdim  // | teams            | for simd        | +                                  |
2173280031Sdim  // | teams            | master          | +                                  |
2174280031Sdim  // | teams            | critical        | +                                  |
2175280031Sdim  // | teams            | simd            | +                                  |
2176280031Sdim  // | teams            | sections        | +                                  |
2177280031Sdim  // | teams            | section         | +                                  |
2178280031Sdim  // | teams            | single          | +                                  |
2179280031Sdim  // | teams            | parallel for    | *                                  |
2180280031Sdim  // | teams            |parallel for simd| *                                  |
2181280031Sdim  // | teams            |parallel sections| *                                  |
2182280031Sdim  // | teams            | task            | +                                  |
2183280031Sdim  // | teams            | taskyield       | +                                  |
2184280031Sdim  // | teams            | barrier         | +                                  |
2185280031Sdim  // | teams            | taskwait        | +                                  |
2186288943Sdim  // | teams            | taskgroup       | +                                  |
2187280031Sdim  // | teams            | flush           | +                                  |
2188280031Sdim  // | teams            | ordered         | +                                  |
2189280031Sdim  // | teams            | atomic          | +                                  |
2190280031Sdim  // | teams            | target          | +                                  |
2191280031Sdim  // | teams            | teams           | +                                  |
2192288943Sdim  // | teams            | cancellation    |                                    |
2193288943Sdim  // |                  | point           |                                    |
2194288943Sdim  // | teams            | cancel          |                                    |
2195296417Sdim  // | teams            | taskloop        | +                                  |
2196296417Sdim  // | teams            | taskloop simd   | +                                  |
2197296417Sdim  // | teams            | distribute      | !                                  |
2198280031Sdim  // +------------------+-----------------+------------------------------------+
2199296417Sdim  // | taskloop         | parallel        | *                                  |
2200296417Sdim  // | taskloop         | for             | +                                  |
2201296417Sdim  // | taskloop         | for simd        | +                                  |
2202296417Sdim  // | taskloop         | master          | +                                  |
2203296417Sdim  // | taskloop         | critical        | *                                  |
2204296417Sdim  // | taskloop         | simd            | *                                  |
2205296417Sdim  // | taskloop         | sections        | +                                  |
2206296417Sdim  // | taskloop         | section         | +                                  |
2207296417Sdim  // | taskloop         | single          | +                                  |
2208296417Sdim  // | taskloop         | parallel for    | *                                  |
2209296417Sdim  // | taskloop         |parallel for simd| *                                  |
2210296417Sdim  // | taskloop         |parallel sections| *                                  |
2211296417Sdim  // | taskloop         | task            | *                                  |
2212296417Sdim  // | taskloop         | taskyield       | *                                  |
2213296417Sdim  // | taskloop         | barrier         | +                                  |
2214296417Sdim  // | taskloop         | taskwait        | *                                  |
2215296417Sdim  // | taskloop         | taskgroup       | *                                  |
2216296417Sdim  // | taskloop         | flush           | *                                  |
2217296417Sdim  // | taskloop         | ordered         | +                                  |
2218296417Sdim  // | taskloop         | atomic          | *                                  |
2219296417Sdim  // | taskloop         | target          | *                                  |
2220296417Sdim  // | taskloop         | teams           | +                                  |
2221296417Sdim  // | taskloop         | cancellation    |                                    |
2222296417Sdim  // |                  | point           |                                    |
2223296417Sdim  // | taskloop         | cancel          |                                    |
2224296417Sdim  // | taskloop         | taskloop        | *                                  |
2225296417Sdim  // | taskloop         | distribute      |                                    |
2226296417Sdim  // +------------------+-----------------+------------------------------------+
2227296417Sdim  // | taskloop simd    | parallel        |                                    |
2228296417Sdim  // | taskloop simd    | for             |                                    |
2229296417Sdim  // | taskloop simd    | for simd        |                                    |
2230296417Sdim  // | taskloop simd    | master          |                                    |
2231296417Sdim  // | taskloop simd    | critical        |                                    |
2232296417Sdim  // | taskloop simd    | simd            |                                    |
2233296417Sdim  // | taskloop simd    | sections        |                                    |
2234296417Sdim  // | taskloop simd    | section         |                                    |
2235296417Sdim  // | taskloop simd    | single          |                                    |
2236296417Sdim  // | taskloop simd    | parallel for    |                                    |
2237296417Sdim  // | taskloop simd    |parallel for simd|                                    |
2238296417Sdim  // | taskloop simd    |parallel sections|                                    |
2239296417Sdim  // | taskloop simd    | task            |                                    |
2240296417Sdim  // | taskloop simd    | taskyield       |                                    |
2241296417Sdim  // | taskloop simd    | barrier         |                                    |
2242296417Sdim  // | taskloop simd    | taskwait        |                                    |
2243296417Sdim  // | taskloop simd    | taskgroup       |                                    |
2244296417Sdim  // | taskloop simd    | flush           |                                    |
2245296417Sdim  // | taskloop simd    | ordered         | + (with simd clause)               |
2246296417Sdim  // | taskloop simd    | atomic          |                                    |
2247296417Sdim  // | taskloop simd    | target          |                                    |
2248296417Sdim  // | taskloop simd    | teams           |                                    |
2249296417Sdim  // | taskloop simd    | cancellation    |                                    |
2250296417Sdim  // |                  | point           |                                    |
2251296417Sdim  // | taskloop simd    | cancel          |                                    |
2252296417Sdim  // | taskloop simd    | taskloop        |                                    |
2253296417Sdim  // | taskloop simd    | taskloop simd   |                                    |
2254296417Sdim  // | taskloop simd    | distribute      |                                    |
2255296417Sdim  // +------------------+-----------------+------------------------------------+
2256296417Sdim  // | distribute       | parallel        | *                                  |
2257296417Sdim  // | distribute       | for             | *                                  |
2258296417Sdim  // | distribute       | for simd        | *                                  |
2259296417Sdim  // | distribute       | master          | *                                  |
2260296417Sdim  // | distribute       | critical        | *                                  |
2261296417Sdim  // | distribute       | simd            | *                                  |
2262296417Sdim  // | distribute       | sections        | *                                  |
2263296417Sdim  // | distribute       | section         | *                                  |
2264296417Sdim  // | distribute       | single          | *                                  |
2265296417Sdim  // | distribute       | parallel for    | *                                  |
2266296417Sdim  // | distribute       |parallel for simd| *                                  |
2267296417Sdim  // | distribute       |parallel sections| *                                  |
2268296417Sdim  // | distribute       | task            | *                                  |
2269296417Sdim  // | distribute       | taskyield       | *                                  |
2270296417Sdim  // | distribute       | barrier         | *                                  |
2271296417Sdim  // | distribute       | taskwait        | *                                  |
2272296417Sdim  // | distribute       | taskgroup       | *                                  |
2273296417Sdim  // | distribute       | flush           | *                                  |
2274296417Sdim  // | distribute       | ordered         | +                                  |
2275296417Sdim  // | distribute       | atomic          | *                                  |
2276296417Sdim  // | distribute       | target          |                                    |
2277296417Sdim  // | distribute       | teams           |                                    |
2278296417Sdim  // | distribute       | cancellation    | +                                  |
2279296417Sdim  // |                  | point           |                                    |
2280296417Sdim  // | distribute       | cancel          | +                                  |
2281296417Sdim  // | distribute       | taskloop        | *                                  |
2282296417Sdim  // | distribute       | taskloop simd   | *                                  |
2283296417Sdim  // | distribute       | distribute      |                                    |
2284296417Sdim  // +------------------+-----------------+------------------------------------+
2285276479Sdim  if (Stack->getCurScope()) {
2286276479Sdim    auto ParentRegion = Stack->getParentDirective();
2287276479Sdim    bool NestingProhibited = false;
2288276479Sdim    bool CloseNesting = true;
2289280031Sdim    enum {
2290280031Sdim      NoRecommend,
2291280031Sdim      ShouldBeInParallelRegion,
2292280031Sdim      ShouldBeInOrderedRegion,
2293296417Sdim      ShouldBeInTargetRegion,
2294296417Sdim      ShouldBeInTeamsRegion
2295280031Sdim    } Recommend = NoRecommend;
2296296417Sdim    if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2297276479Sdim      // OpenMP [2.16, Nesting of Regions]
2298276479Sdim      // OpenMP constructs may not be nested inside a simd region.
2299296417Sdim      // OpenMP [2.8.1,simd Construct, Restrictions]
2300296417Sdim      // An ordered construct with the simd clause is the only OpenMP construct
2301296417Sdim      // that can appear in the simd region.
2302276479Sdim      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
2303276479Sdim      return true;
2304276479Sdim    }
2305280031Sdim    if (ParentRegion == OMPD_atomic) {
2306280031Sdim      // OpenMP [2.16, Nesting of Regions]
2307280031Sdim      // OpenMP constructs may not be nested inside an atomic region.
2308280031Sdim      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2309280031Sdim      return true;
2310280031Sdim    }
2311276479Sdim    if (CurrentRegion == OMPD_section) {
2312276479Sdim      // OpenMP [2.7.2, sections Construct, Restrictions]
2313276479Sdim      // Orphaned section directives are prohibited. That is, the section
2314276479Sdim      // directives must appear within the sections construct and must not be
2315276479Sdim      // encountered elsewhere in the sections region.
2316276479Sdim      if (ParentRegion != OMPD_sections &&
2317276479Sdim          ParentRegion != OMPD_parallel_sections) {
2318276479Sdim        SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2319276479Sdim            << (ParentRegion != OMPD_unknown)
2320276479Sdim            << getOpenMPDirectiveName(ParentRegion);
2321276479Sdim        return true;
2322276479Sdim      }
2323276479Sdim      return false;
2324276479Sdim    }
2325280031Sdim    // Allow some constructs to be orphaned (they could be used in functions,
2326280031Sdim    // called from OpenMP regions with the required preconditions).
2327280031Sdim    if (ParentRegion == OMPD_unknown)
2328280031Sdim      return false;
2329288943Sdim    if (CurrentRegion == OMPD_cancellation_point ||
2330288943Sdim        CurrentRegion == OMPD_cancel) {
2331276479Sdim      // OpenMP [2.16, Nesting of Regions]
2332288943Sdim      // A cancellation point construct for which construct-type-clause is
2333288943Sdim      // taskgroup must be nested inside a task construct. A cancellation
2334288943Sdim      // point construct for which construct-type-clause is not taskgroup must
2335288943Sdim      // be closely nested inside an OpenMP construct that matches the type
2336288943Sdim      // specified in construct-type-clause.
2337288943Sdim      // A cancel construct for which construct-type-clause is taskgroup must be
2338288943Sdim      // nested inside a task construct. A cancel construct for which
2339288943Sdim      // construct-type-clause is not taskgroup must be closely nested inside an
2340288943Sdim      // OpenMP construct that matches the type specified in
2341288943Sdim      // construct-type-clause.
2342288943Sdim      NestingProhibited =
2343288943Sdim          !((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) ||
2344296417Sdim            (CancelRegion == OMPD_for &&
2345296417Sdim             (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for)) ||
2346288943Sdim            (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2347288943Sdim            (CancelRegion == OMPD_sections &&
2348296417Sdim             (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2349296417Sdim              ParentRegion == OMPD_parallel_sections)));
2350288943Sdim    } else if (CurrentRegion == OMPD_master) {
2351288943Sdim      // OpenMP [2.16, Nesting of Regions]
2352276479Sdim      // A master region may not be closely nested inside a worksharing,
2353280031Sdim      // atomic, or explicit task region.
2354276479Sdim      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2355296417Sdim                          ParentRegion == OMPD_task ||
2356296417Sdim                          isOpenMPTaskLoopDirective(ParentRegion);
2357276479Sdim    } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2358276479Sdim      // OpenMP [2.16, Nesting of Regions]
2359276479Sdim      // A critical region may not be nested (closely or otherwise) inside a
2360276479Sdim      // critical region with the same name. Note that this restriction is not
2361276479Sdim      // sufficient to prevent deadlock.
2362276479Sdim      SourceLocation PreviousCriticalLoc;
2363276479Sdim      bool DeadLock =
2364276479Sdim          Stack->hasDirective([CurrentName, &PreviousCriticalLoc](
2365276479Sdim                                  OpenMPDirectiveKind K,
2366276479Sdim                                  const DeclarationNameInfo &DNI,
2367276479Sdim                                  SourceLocation Loc)
2368276479Sdim                                  ->bool {
2369276479Sdim                                if (K == OMPD_critical &&
2370276479Sdim                                    DNI.getName() == CurrentName.getName()) {
2371276479Sdim                                  PreviousCriticalLoc = Loc;
2372276479Sdim                                  return true;
2373276479Sdim                                } else
2374276479Sdim                                  return false;
2375276479Sdim                              },
2376276479Sdim                              false /* skip top directive */);
2377276479Sdim      if (DeadLock) {
2378276479Sdim        SemaRef.Diag(StartLoc,
2379276479Sdim                     diag::err_omp_prohibited_region_critical_same_name)
2380276479Sdim            << CurrentName.getName();
2381276479Sdim        if (PreviousCriticalLoc.isValid())
2382276479Sdim          SemaRef.Diag(PreviousCriticalLoc,
2383276479Sdim                       diag::note_omp_previous_critical_region);
2384276479Sdim        return true;
2385276479Sdim      }
2386276479Sdim    } else if (CurrentRegion == OMPD_barrier) {
2387276479Sdim      // OpenMP [2.16, Nesting of Regions]
2388276479Sdim      // A barrier region may not be closely nested inside a worksharing,
2389280031Sdim      // explicit task, critical, ordered, atomic, or master region.
2390280031Sdim      NestingProhibited =
2391280031Sdim          isOpenMPWorksharingDirective(ParentRegion) ||
2392280031Sdim          ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
2393296417Sdim          ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered ||
2394296417Sdim          isOpenMPTaskLoopDirective(ParentRegion);
2395276479Sdim    } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2396280031Sdim               !isOpenMPParallelDirective(CurrentRegion)) {
2397276479Sdim      // OpenMP [2.16, Nesting of Regions]
2398276479Sdim      // A worksharing region may not be closely nested inside a worksharing,
2399276479Sdim      // explicit task, critical, ordered, atomic, or master region.
2400280031Sdim      NestingProhibited =
2401280031Sdim          isOpenMPWorksharingDirective(ParentRegion) ||
2402280031Sdim          ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
2403296417Sdim          ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered ||
2404296417Sdim          isOpenMPTaskLoopDirective(ParentRegion);
2405280031Sdim      Recommend = ShouldBeInParallelRegion;
2406280031Sdim    } else if (CurrentRegion == OMPD_ordered) {
2407280031Sdim      // OpenMP [2.16, Nesting of Regions]
2408280031Sdim      // An ordered region may not be closely nested inside a critical,
2409280031Sdim      // atomic, or explicit task region.
2410280031Sdim      // An ordered region must be closely nested inside a loop region (or
2411280031Sdim      // parallel loop region) with an ordered clause.
2412296417Sdim      // OpenMP [2.8.1,simd Construct, Restrictions]
2413296417Sdim      // An ordered construct with the simd clause is the only OpenMP construct
2414296417Sdim      // that can appear in the simd region.
2415280031Sdim      NestingProhibited = ParentRegion == OMPD_critical ||
2416276479Sdim                          ParentRegion == OMPD_task ||
2417296417Sdim                          isOpenMPTaskLoopDirective(ParentRegion) ||
2418296417Sdim                          !(isOpenMPSimdDirective(ParentRegion) ||
2419296417Sdim                            Stack->isParentOrderedRegion());
2420280031Sdim      Recommend = ShouldBeInOrderedRegion;
2421280031Sdim    } else if (isOpenMPTeamsDirective(CurrentRegion)) {
2422280031Sdim      // OpenMP [2.16, Nesting of Regions]
2423280031Sdim      // If specified, a teams construct must be contained within a target
2424280031Sdim      // construct.
2425280031Sdim      NestingProhibited = ParentRegion != OMPD_target;
2426280031Sdim      Recommend = ShouldBeInTargetRegion;
2427280031Sdim      Stack->setParentTeamsRegionLoc(Stack->getConstructLoc());
2428276479Sdim    }
2429280031Sdim    if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) {
2430280031Sdim      // OpenMP [2.16, Nesting of Regions]
2431280031Sdim      // distribute, parallel, parallel sections, parallel workshare, and the
2432280031Sdim      // parallel loop and parallel loop SIMD constructs are the only OpenMP
2433280031Sdim      // constructs that can be closely nested in the teams region.
2434296417Sdim      NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2435296417Sdim                          !isOpenMPDistributeDirective(CurrentRegion);
2436280031Sdim      Recommend = ShouldBeInParallelRegion;
2437280031Sdim    }
2438296417Sdim    if (!NestingProhibited && isOpenMPDistributeDirective(CurrentRegion)) {
2439296417Sdim      // OpenMP 4.5 [2.17 Nesting of Regions]
2440296417Sdim      // The region associated with the distribute construct must be strictly
2441296417Sdim      // nested inside a teams region
2442296417Sdim      NestingProhibited = !isOpenMPTeamsDirective(ParentRegion);
2443296417Sdim      Recommend = ShouldBeInTeamsRegion;
2444296417Sdim    }
2445276479Sdim    if (NestingProhibited) {
2446276479Sdim      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2447280031Sdim          << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend
2448280031Sdim          << getOpenMPDirectiveName(CurrentRegion);
2449276479Sdim      return true;
2450276479Sdim    }
2451276479Sdim  }
2452276479Sdim  return false;
2453276479Sdim}
2454276479Sdim
2455296417Sdimstatic bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
2456296417Sdim                           ArrayRef<OMPClause *> Clauses,
2457296417Sdim                           ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2458296417Sdim  bool ErrorFound = false;
2459296417Sdim  unsigned NamedModifiersNumber = 0;
2460296417Sdim  SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
2461296417Sdim      OMPD_unknown + 1);
2462296417Sdim  SmallVector<SourceLocation, 4> NameModifierLoc;
2463296417Sdim  for (const auto *C : Clauses) {
2464296417Sdim    if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2465296417Sdim      // At most one if clause without a directive-name-modifier can appear on
2466296417Sdim      // the directive.
2467296417Sdim      OpenMPDirectiveKind CurNM = IC->getNameModifier();
2468296417Sdim      if (FoundNameModifiers[CurNM]) {
2469296417Sdim        S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
2470296417Sdim            << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
2471296417Sdim            << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
2472296417Sdim        ErrorFound = true;
2473296417Sdim      } else if (CurNM != OMPD_unknown) {
2474296417Sdim        NameModifierLoc.push_back(IC->getNameModifierLoc());
2475296417Sdim        ++NamedModifiersNumber;
2476296417Sdim      }
2477296417Sdim      FoundNameModifiers[CurNM] = IC;
2478296417Sdim      if (CurNM == OMPD_unknown)
2479296417Sdim        continue;
2480296417Sdim      // Check if the specified name modifier is allowed for the current
2481296417Sdim      // directive.
2482296417Sdim      // At most one if clause with the particular directive-name-modifier can
2483296417Sdim      // appear on the directive.
2484296417Sdim      bool MatchFound = false;
2485296417Sdim      for (auto NM : AllowedNameModifiers) {
2486296417Sdim        if (CurNM == NM) {
2487296417Sdim          MatchFound = true;
2488296417Sdim          break;
2489296417Sdim        }
2490296417Sdim      }
2491296417Sdim      if (!MatchFound) {
2492296417Sdim        S.Diag(IC->getNameModifierLoc(),
2493296417Sdim               diag::err_omp_wrong_if_directive_name_modifier)
2494296417Sdim            << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
2495296417Sdim        ErrorFound = true;
2496296417Sdim      }
2497296417Sdim    }
2498296417Sdim  }
2499296417Sdim  // If any if clause on the directive includes a directive-name-modifier then
2500296417Sdim  // all if clauses on the directive must include a directive-name-modifier.
2501296417Sdim  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
2502296417Sdim    if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2503296417Sdim      S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
2504296417Sdim             diag::err_omp_no_more_if_clause);
2505296417Sdim    } else {
2506296417Sdim      std::string Values;
2507296417Sdim      std::string Sep(", ");
2508296417Sdim      unsigned AllowedCnt = 0;
2509296417Sdim      unsigned TotalAllowedNum =
2510296417Sdim          AllowedNameModifiers.size() - NamedModifiersNumber;
2511296417Sdim      for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
2512296417Sdim           ++Cnt) {
2513296417Sdim        OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
2514296417Sdim        if (!FoundNameModifiers[NM]) {
2515296417Sdim          Values += "'";
2516296417Sdim          Values += getOpenMPDirectiveName(NM);
2517296417Sdim          Values += "'";
2518296417Sdim          if (AllowedCnt + 2 == TotalAllowedNum)
2519296417Sdim            Values += " or ";
2520296417Sdim          else if (AllowedCnt + 1 != TotalAllowedNum)
2521296417Sdim            Values += Sep;
2522296417Sdim          ++AllowedCnt;
2523296417Sdim        }
2524296417Sdim      }
2525296417Sdim      S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
2526296417Sdim             diag::err_omp_unnamed_if_clause)
2527296417Sdim          << (TotalAllowedNum > 1) << Values;
2528296417Sdim    }
2529296417Sdim    for (auto Loc : NameModifierLoc) {
2530296417Sdim      S.Diag(Loc, diag::note_omp_previous_named_if_clause);
2531296417Sdim    }
2532296417Sdim    ErrorFound = true;
2533296417Sdim  }
2534296417Sdim  return ErrorFound;
2535296417Sdim}
2536296417Sdim
2537288943SdimStmtResult Sema::ActOnOpenMPExecutableDirective(
2538288943Sdim    OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
2539288943Sdim    OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
2540288943Sdim    Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
2541261991Sdim  StmtResult Res = StmtError();
2542288943Sdim  if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
2543288943Sdim                            StartLoc))
2544276479Sdim    return StmtError();
2545261991Sdim
2546261991Sdim  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
2547276479Sdim  llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
2548276479Sdim  bool ErrorFound = false;
2549261991Sdim  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2550276479Sdim  if (AStmt) {
2551276479Sdim    assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
2552261991Sdim
2553276479Sdim    // Check default data sharing attributes for referenced variables.
2554276479Sdim    DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
2555276479Sdim    DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
2556276479Sdim    if (DSAChecker.isErrorFound())
2557276479Sdim      return StmtError();
2558276479Sdim    // Generate list of implicitly defined firstprivate variables.
2559276479Sdim    VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2560276479Sdim
2561276479Sdim    if (!DSAChecker.getImplicitFirstprivate().empty()) {
2562276479Sdim      if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2563276479Sdim              DSAChecker.getImplicitFirstprivate(), SourceLocation(),
2564276479Sdim              SourceLocation(), SourceLocation())) {
2565276479Sdim        ClausesWithImplicit.push_back(Implicit);
2566276479Sdim        ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2567276479Sdim                     DSAChecker.getImplicitFirstprivate().size();
2568276479Sdim      } else
2569276479Sdim        ErrorFound = true;
2570276479Sdim    }
2571261991Sdim  }
2572261991Sdim
2573296417Sdim  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
2574261991Sdim  switch (Kind) {
2575261991Sdim  case OMPD_parallel:
2576276479Sdim    Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
2577276479Sdim                                       EndLoc);
2578296417Sdim    AllowedNameModifiers.push_back(OMPD_parallel);
2579261991Sdim    break;
2580276479Sdim  case OMPD_simd:
2581276479Sdim    Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2582276479Sdim                                   VarsWithInheritedDSA);
2583276479Sdim    break;
2584276479Sdim  case OMPD_for:
2585276479Sdim    Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2586276479Sdim                                  VarsWithInheritedDSA);
2587276479Sdim    break;
2588280031Sdim  case OMPD_for_simd:
2589280031Sdim    Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2590280031Sdim                                      EndLoc, VarsWithInheritedDSA);
2591280031Sdim    break;
2592276479Sdim  case OMPD_sections:
2593276479Sdim    Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
2594276479Sdim                                       EndLoc);
2595276479Sdim    break;
2596276479Sdim  case OMPD_section:
2597276479Sdim    assert(ClausesWithImplicit.empty() &&
2598276479Sdim           "No clauses are allowed for 'omp section' directive");
2599276479Sdim    Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
2600276479Sdim    break;
2601276479Sdim  case OMPD_single:
2602276479Sdim    Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
2603276479Sdim                                     EndLoc);
2604276479Sdim    break;
2605276479Sdim  case OMPD_master:
2606276479Sdim    assert(ClausesWithImplicit.empty() &&
2607276479Sdim           "No clauses are allowed for 'omp master' directive");
2608276479Sdim    Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
2609276479Sdim    break;
2610276479Sdim  case OMPD_critical:
2611296417Sdim    Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
2612296417Sdim                                       StartLoc, EndLoc);
2613276479Sdim    break;
2614276479Sdim  case OMPD_parallel_for:
2615276479Sdim    Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
2616276479Sdim                                          EndLoc, VarsWithInheritedDSA);
2617296417Sdim    AllowedNameModifiers.push_back(OMPD_parallel);
2618276479Sdim    break;
2619280031Sdim  case OMPD_parallel_for_simd:
2620280031Sdim    Res = ActOnOpenMPParallelForSimdDirective(
2621280031Sdim        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2622296417Sdim    AllowedNameModifiers.push_back(OMPD_parallel);
2623280031Sdim    break;
2624276479Sdim  case OMPD_parallel_sections:
2625276479Sdim    Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
2626276479Sdim                                               StartLoc, EndLoc);
2627296417Sdim    AllowedNameModifiers.push_back(OMPD_parallel);
2628276479Sdim    break;
2629276479Sdim  case OMPD_task:
2630276479Sdim    Res =
2631276479Sdim        ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2632296417Sdim    AllowedNameModifiers.push_back(OMPD_task);
2633276479Sdim    break;
2634276479Sdim  case OMPD_taskyield:
2635276479Sdim    assert(ClausesWithImplicit.empty() &&
2636276479Sdim           "No clauses are allowed for 'omp taskyield' directive");
2637276479Sdim    assert(AStmt == nullptr &&
2638276479Sdim           "No associated statement allowed for 'omp taskyield' directive");
2639276479Sdim    Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
2640276479Sdim    break;
2641276479Sdim  case OMPD_barrier:
2642276479Sdim    assert(ClausesWithImplicit.empty() &&
2643276479Sdim           "No clauses are allowed for 'omp barrier' directive");
2644276479Sdim    assert(AStmt == nullptr &&
2645276479Sdim           "No associated statement allowed for 'omp barrier' directive");
2646276479Sdim    Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
2647276479Sdim    break;
2648276479Sdim  case OMPD_taskwait:
2649276479Sdim    assert(ClausesWithImplicit.empty() &&
2650276479Sdim           "No clauses are allowed for 'omp taskwait' directive");
2651276479Sdim    assert(AStmt == nullptr &&
2652276479Sdim           "No associated statement allowed for 'omp taskwait' directive");
2653276479Sdim    Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
2654276479Sdim    break;
2655288943Sdim  case OMPD_taskgroup:
2656288943Sdim    assert(ClausesWithImplicit.empty() &&
2657288943Sdim           "No clauses are allowed for 'omp taskgroup' directive");
2658288943Sdim    Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc);
2659288943Sdim    break;
2660276479Sdim  case OMPD_flush:
2661276479Sdim    assert(AStmt == nullptr &&
2662276479Sdim           "No associated statement allowed for 'omp flush' directive");
2663276479Sdim    Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
2664276479Sdim    break;
2665280031Sdim  case OMPD_ordered:
2666296417Sdim    Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
2667296417Sdim                                      EndLoc);
2668280031Sdim    break;
2669280031Sdim  case OMPD_atomic:
2670280031Sdim    Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
2671280031Sdim                                     EndLoc);
2672280031Sdim    break;
2673280031Sdim  case OMPD_teams:
2674280031Sdim    Res =
2675280031Sdim        ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2676280031Sdim    break;
2677280031Sdim  case OMPD_target:
2678280031Sdim    Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
2679280031Sdim                                     EndLoc);
2680296417Sdim    AllowedNameModifiers.push_back(OMPD_target);
2681280031Sdim    break;
2682288943Sdim  case OMPD_cancellation_point:
2683288943Sdim    assert(ClausesWithImplicit.empty() &&
2684288943Sdim           "No clauses are allowed for 'omp cancellation point' directive");
2685288943Sdim    assert(AStmt == nullptr && "No associated statement allowed for 'omp "
2686288943Sdim                               "cancellation point' directive");
2687288943Sdim    Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
2688288943Sdim    break;
2689288943Sdim  case OMPD_cancel:
2690288943Sdim    assert(AStmt == nullptr &&
2691288943Sdim           "No associated statement allowed for 'omp cancel' directive");
2692296417Sdim    Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
2693296417Sdim                                     CancelRegion);
2694296417Sdim    AllowedNameModifiers.push_back(OMPD_cancel);
2695288943Sdim    break;
2696296417Sdim  case OMPD_target_data:
2697296417Sdim    Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
2698296417Sdim                                         EndLoc);
2699296417Sdim    AllowedNameModifiers.push_back(OMPD_target_data);
2700296417Sdim    break;
2701296417Sdim  case OMPD_taskloop:
2702296417Sdim    Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
2703296417Sdim                                       EndLoc, VarsWithInheritedDSA);
2704296417Sdim    AllowedNameModifiers.push_back(OMPD_taskloop);
2705296417Sdim    break;
2706296417Sdim  case OMPD_taskloop_simd:
2707296417Sdim    Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2708296417Sdim                                           EndLoc, VarsWithInheritedDSA);
2709296417Sdim    AllowedNameModifiers.push_back(OMPD_taskloop);
2710296417Sdim    break;
2711296417Sdim  case OMPD_distribute:
2712296417Sdim    Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
2713296417Sdim                                         EndLoc, VarsWithInheritedDSA);
2714296417Sdim    break;
2715261991Sdim  case OMPD_threadprivate:
2716261991Sdim    llvm_unreachable("OpenMP Directive is not allowed");
2717261991Sdim  case OMPD_unknown:
2718261991Sdim    llvm_unreachable("Unknown OpenMP directive");
2719261991Sdim  }
2720261991Sdim
2721276479Sdim  for (auto P : VarsWithInheritedDSA) {
2722276479Sdim    Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
2723276479Sdim        << P.first << P.second->getSourceRange();
2724276479Sdim  }
2725296417Sdim  ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
2726276479Sdim
2727296417Sdim  if (!AllowedNameModifiers.empty())
2728296417Sdim    ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
2729296417Sdim                 ErrorFound;
2730296417Sdim
2731276479Sdim  if (ErrorFound)
2732276479Sdim    return StmtError();
2733261991Sdim  return Res;
2734261991Sdim}
2735261991Sdim
2736261991SdimStmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
2737261991Sdim                                              Stmt *AStmt,
2738261991Sdim                                              SourceLocation StartLoc,
2739261991Sdim                                              SourceLocation EndLoc) {
2740296417Sdim  if (!AStmt)
2741296417Sdim    return StmtError();
2742296417Sdim
2743276479Sdim  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
2744276479Sdim  // 1.2.2 OpenMP Language Terminology
2745276479Sdim  // Structured block - An executable statement with a single entry at the
2746276479Sdim  // top and a single exit at the bottom.
2747276479Sdim  // The point of exit cannot be a branch out of the structured block.
2748276479Sdim  // longjmp() and throw() must not violate the entry/exit criteria.
2749276479Sdim  CS->getCapturedDecl()->setNothrow();
2750276479Sdim
2751261991Sdim  getCurFunction()->setHasBranchProtectedScope();
2752261991Sdim
2753296417Sdim  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
2754296417Sdim                                      DSAStack->isCancelRegion());
2755261991Sdim}
2756261991Sdim
2757276479Sdimnamespace {
2758276479Sdim/// \brief Helper class for checking canonical form of the OpenMP loops and
2759276479Sdim/// extracting iteration space of each loop in the loop nest, that will be used
2760276479Sdim/// for IR generation.
2761276479Sdimclass OpenMPIterationSpaceChecker {
2762276479Sdim  /// \brief Reference to Sema.
2763276479Sdim  Sema &SemaRef;
2764276479Sdim  /// \brief A location for diagnostics (when there is no some better location).
2765276479Sdim  SourceLocation DefaultLoc;
2766276479Sdim  /// \brief A location for diagnostics (when increment is not compatible).
2767276479Sdim  SourceLocation ConditionLoc;
2768280031Sdim  /// \brief A source location for referring to loop init later.
2769280031Sdim  SourceRange InitSrcRange;
2770276479Sdim  /// \brief A source location for referring to condition later.
2771276479Sdim  SourceRange ConditionSrcRange;
2772280031Sdim  /// \brief A source location for referring to increment later.
2773280031Sdim  SourceRange IncrementSrcRange;
2774276479Sdim  /// \brief Loop variable.
2775276479Sdim  VarDecl *Var;
2776280031Sdim  /// \brief Reference to loop variable.
2777280031Sdim  DeclRefExpr *VarRef;
2778276479Sdim  /// \brief Lower bound (initializer for the var).
2779276479Sdim  Expr *LB;
2780276479Sdim  /// \brief Upper bound.
2781276479Sdim  Expr *UB;
2782276479Sdim  /// \brief Loop step (increment).
2783276479Sdim  Expr *Step;
2784276479Sdim  /// \brief This flag is true when condition is one of:
2785276479Sdim  ///   Var <  UB
2786276479Sdim  ///   Var <= UB
2787276479Sdim  ///   UB  >  Var
2788276479Sdim  ///   UB  >= Var
2789276479Sdim  bool TestIsLessOp;
2790276479Sdim  /// \brief This flag is true when condition is strict ( < or > ).
2791276479Sdim  bool TestIsStrictOp;
2792276479Sdim  /// \brief This flag is true when step is subtracted on each iteration.
2793276479Sdim  bool SubtractStep;
2794276479Sdim
2795276479Sdimpublic:
2796276479Sdim  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
2797276479Sdim      : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc),
2798280031Sdim        InitSrcRange(SourceRange()), ConditionSrcRange(SourceRange()),
2799280031Sdim        IncrementSrcRange(SourceRange()), Var(nullptr), VarRef(nullptr),
2800280031Sdim        LB(nullptr), UB(nullptr), Step(nullptr), TestIsLessOp(false),
2801280031Sdim        TestIsStrictOp(false), SubtractStep(false) {}
2802276479Sdim  /// \brief Check init-expr for canonical loop form and save loop counter
2803276479Sdim  /// variable - #Var and its initialization value - #LB.
2804288943Sdim  bool CheckInit(Stmt *S, bool EmitDiags = true);
2805276479Sdim  /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
2806276479Sdim  /// for less/greater and for strict/non-strict comparison.
2807276479Sdim  bool CheckCond(Expr *S);
2808276479Sdim  /// \brief Check incr-expr for canonical loop form and return true if it
2809276479Sdim  /// does not conform, otherwise save loop step (#Step).
2810276479Sdim  bool CheckInc(Expr *S);
2811276479Sdim  /// \brief Return the loop counter variable.
2812276479Sdim  VarDecl *GetLoopVar() const { return Var; }
2813280031Sdim  /// \brief Return the reference expression to loop counter variable.
2814280031Sdim  DeclRefExpr *GetLoopVarRefExpr() const { return VarRef; }
2815280031Sdim  /// \brief Source range of the loop init.
2816280031Sdim  SourceRange GetInitSrcRange() const { return InitSrcRange; }
2817280031Sdim  /// \brief Source range of the loop condition.
2818280031Sdim  SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
2819280031Sdim  /// \brief Source range of the loop increment.
2820280031Sdim  SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
2821280031Sdim  /// \brief True if the step should be subtracted.
2822280031Sdim  bool ShouldSubtractStep() const { return SubtractStep; }
2823280031Sdim  /// \brief Build the expression to calculate the number of iterations.
2824280031Sdim  Expr *BuildNumIterations(Scope *S, const bool LimitedType) const;
2825288943Sdim  /// \brief Build the precondition expression for the loops.
2826288943Sdim  Expr *BuildPreCond(Scope *S, Expr *Cond) const;
2827280031Sdim  /// \brief Build reference expression to the counter be used for codegen.
2828280031Sdim  Expr *BuildCounterVar() const;
2829296417Sdim  /// \brief Build reference expression to the private counter be used for
2830296417Sdim  /// codegen.
2831296417Sdim  Expr *BuildPrivateCounterVar() const;
2832280031Sdim  /// \brief Build initization of the counter be used for codegen.
2833280031Sdim  Expr *BuildCounterInit() const;
2834280031Sdim  /// \brief Build step of the counter be used for codegen.
2835280031Sdim  Expr *BuildCounterStep() const;
2836276479Sdim  /// \brief Return true if any expression is dependent.
2837276479Sdim  bool Dependent() const;
2838276479Sdim
2839276479Sdimprivate:
2840276479Sdim  /// \brief Check the right-hand side of an assignment in the increment
2841276479Sdim  /// expression.
2842276479Sdim  bool CheckIncRHS(Expr *RHS);
2843276479Sdim  /// \brief Helper to set loop counter variable and its initializer.
2844280031Sdim  bool SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB);
2845276479Sdim  /// \brief Helper to set upper bound.
2846296417Sdim  bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
2847296417Sdim             SourceLocation SL);
2848276479Sdim  /// \brief Helper to set loop increment.
2849276479Sdim  bool SetStep(Expr *NewStep, bool Subtract);
2850276479Sdim};
2851276479Sdim
2852276479Sdimbool OpenMPIterationSpaceChecker::Dependent() const {
2853276479Sdim  if (!Var) {
2854276479Sdim    assert(!LB && !UB && !Step);
2855276479Sdim    return false;
2856276479Sdim  }
2857276479Sdim  return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) ||
2858276479Sdim         (UB && UB->isValueDependent()) || (Step && Step->isValueDependent());
2859276479Sdim}
2860276479Sdim
2861288943Sdimtemplate <typename T>
2862288943Sdimstatic T *getExprAsWritten(T *E) {
2863288943Sdim  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
2864288943Sdim    E = ExprTemp->getSubExpr();
2865288943Sdim
2866288943Sdim  if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
2867288943Sdim    E = MTE->GetTemporaryExpr();
2868288943Sdim
2869288943Sdim  while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
2870288943Sdim    E = Binder->getSubExpr();
2871288943Sdim
2872288943Sdim  if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
2873288943Sdim    E = ICE->getSubExprAsWritten();
2874288943Sdim  return E->IgnoreParens();
2875288943Sdim}
2876288943Sdim
2877280031Sdimbool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar,
2878280031Sdim                                              DeclRefExpr *NewVarRefExpr,
2879280031Sdim                                              Expr *NewLB) {
2880276479Sdim  // State consistency checking to ensure correct usage.
2881280031Sdim  assert(Var == nullptr && LB == nullptr && VarRef == nullptr &&
2882280031Sdim         UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
2883276479Sdim  if (!NewVar || !NewLB)
2884276479Sdim    return true;
2885276479Sdim  Var = NewVar;
2886280031Sdim  VarRef = NewVarRefExpr;
2887288943Sdim  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
2888288943Sdim    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
2889288943Sdim      if ((Ctor->isCopyOrMoveConstructor() ||
2890288943Sdim           Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
2891288943Sdim          CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
2892288943Sdim        NewLB = CE->getArg(0)->IgnoreParenImpCasts();
2893276479Sdim  LB = NewLB;
2894276479Sdim  return false;
2895276479Sdim}
2896276479Sdim
2897276479Sdimbool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
2898296417Sdim                                        SourceRange SR, SourceLocation SL) {
2899276479Sdim  // State consistency checking to ensure correct usage.
2900276479Sdim  assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr &&
2901276479Sdim         !TestIsLessOp && !TestIsStrictOp);
2902276479Sdim  if (!NewUB)
2903276479Sdim    return true;
2904276479Sdim  UB = NewUB;
2905276479Sdim  TestIsLessOp = LessOp;
2906276479Sdim  TestIsStrictOp = StrictOp;
2907276479Sdim  ConditionSrcRange = SR;
2908276479Sdim  ConditionLoc = SL;
2909276479Sdim  return false;
2910276479Sdim}
2911276479Sdim
2912276479Sdimbool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
2913276479Sdim  // State consistency checking to ensure correct usage.
2914276479Sdim  assert(Var != nullptr && LB != nullptr && Step == nullptr);
2915276479Sdim  if (!NewStep)
2916276479Sdim    return true;
2917276479Sdim  if (!NewStep->isValueDependent()) {
2918276479Sdim    // Check that the step is integer expression.
2919276479Sdim    SourceLocation StepLoc = NewStep->getLocStart();
2920276479Sdim    ExprResult Val =
2921276479Sdim        SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
2922276479Sdim    if (Val.isInvalid())
2923276479Sdim      return true;
2924276479Sdim    NewStep = Val.get();
2925276479Sdim
2926276479Sdim    // OpenMP [2.6, Canonical Loop Form, Restrictions]
2927276479Sdim    //  If test-expr is of form var relational-op b and relational-op is < or
2928276479Sdim    //  <= then incr-expr must cause var to increase on each iteration of the
2929276479Sdim    //  loop. If test-expr is of form var relational-op b and relational-op is
2930276479Sdim    //  > or >= then incr-expr must cause var to decrease on each iteration of
2931276479Sdim    //  the loop.
2932276479Sdim    //  If test-expr is of form b relational-op var and relational-op is < or
2933276479Sdim    //  <= then incr-expr must cause var to decrease on each iteration of the
2934276479Sdim    //  loop. If test-expr is of form b relational-op var and relational-op is
2935276479Sdim    //  > or >= then incr-expr must cause var to increase on each iteration of
2936276479Sdim    //  the loop.
2937276479Sdim    llvm::APSInt Result;
2938276479Sdim    bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
2939276479Sdim    bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
2940276479Sdim    bool IsConstNeg =
2941276479Sdim        IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
2942280031Sdim    bool IsConstPos =
2943280031Sdim        IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
2944276479Sdim    bool IsConstZero = IsConstant && !Result.getBoolValue();
2945276479Sdim    if (UB && (IsConstZero ||
2946276479Sdim               (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
2947280031Sdim                             : (IsConstPos || (IsUnsigned && !Subtract))))) {
2948276479Sdim      SemaRef.Diag(NewStep->getExprLoc(),
2949276479Sdim                   diag::err_omp_loop_incr_not_compatible)
2950276479Sdim          << Var << TestIsLessOp << NewStep->getSourceRange();
2951276479Sdim      SemaRef.Diag(ConditionLoc,
2952276479Sdim                   diag::note_omp_loop_cond_requres_compatible_incr)
2953276479Sdim          << TestIsLessOp << ConditionSrcRange;
2954276479Sdim      return true;
2955276479Sdim    }
2956280031Sdim    if (TestIsLessOp == Subtract) {
2957280031Sdim      NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus,
2958280031Sdim                                             NewStep).get();
2959280031Sdim      Subtract = !Subtract;
2960280031Sdim    }
2961276479Sdim  }
2962276479Sdim
2963276479Sdim  Step = NewStep;
2964276479Sdim  SubtractStep = Subtract;
2965276479Sdim  return false;
2966276479Sdim}
2967276479Sdim
2968288943Sdimbool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
2969276479Sdim  // Check init-expr for canonical loop form and save loop counter
2970276479Sdim  // variable - #Var and its initialization value - #LB.
2971276479Sdim  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
2972276479Sdim  //   var = lb
2973276479Sdim  //   integer-type var = lb
2974276479Sdim  //   random-access-iterator-type var = lb
2975276479Sdim  //   pointer-type var = lb
2976276479Sdim  //
2977276479Sdim  if (!S) {
2978288943Sdim    if (EmitDiags) {
2979288943Sdim      SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
2980288943Sdim    }
2981276479Sdim    return true;
2982276479Sdim  }
2983280031Sdim  InitSrcRange = S->getSourceRange();
2984276479Sdim  if (Expr *E = dyn_cast<Expr>(S))
2985276479Sdim    S = E->IgnoreParens();
2986276479Sdim  if (auto BO = dyn_cast<BinaryOperator>(S)) {
2987276479Sdim    if (BO->getOpcode() == BO_Assign)
2988276479Sdim      if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens()))
2989280031Sdim        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
2990280031Sdim                           BO->getRHS());
2991276479Sdim  } else if (auto DS = dyn_cast<DeclStmt>(S)) {
2992276479Sdim    if (DS->isSingleDecl()) {
2993276479Sdim      if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
2994296417Sdim        if (Var->hasInit() && !Var->getType()->isReferenceType()) {
2995276479Sdim          // Accept non-canonical init form here but emit ext. warning.
2996288943Sdim          if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
2997276479Sdim            SemaRef.Diag(S->getLocStart(),
2998276479Sdim                         diag::ext_omp_loop_not_canonical_init)
2999276479Sdim                << S->getSourceRange();
3000280031Sdim          return SetVarAndLB(Var, nullptr, Var->getInit());
3001276479Sdim        }
3002276479Sdim      }
3003276479Sdim    }
3004276479Sdim  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S))
3005276479Sdim    if (CE->getOperator() == OO_Equal)
3006276479Sdim      if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0)))
3007280031Sdim        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
3008280031Sdim                           CE->getArg(1));
3009276479Sdim
3010288943Sdim  if (EmitDiags) {
3011288943Sdim    SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3012288943Sdim        << S->getSourceRange();
3013288943Sdim  }
3014276479Sdim  return true;
3015276479Sdim}
3016276479Sdim
3017276479Sdim/// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
3018276479Sdim/// variable (which may be the loop variable) if possible.
3019276479Sdimstatic const VarDecl *GetInitVarDecl(const Expr *E) {
3020276479Sdim  if (!E)
3021276479Sdim    return nullptr;
3022288943Sdim  E = getExprAsWritten(E);
3023276479Sdim  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3024276479Sdim    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3025288943Sdim      if ((Ctor->isCopyOrMoveConstructor() ||
3026288943Sdim           Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3027288943Sdim          CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3028276479Sdim        E = CE->getArg(0)->IgnoreParenImpCasts();
3029276479Sdim  auto DRE = dyn_cast_or_null<DeclRefExpr>(E);
3030276479Sdim  if (!DRE)
3031276479Sdim    return nullptr;
3032276479Sdim  return dyn_cast<VarDecl>(DRE->getDecl());
3033276479Sdim}
3034276479Sdim
3035276479Sdimbool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
3036276479Sdim  // Check test-expr for canonical form, save upper-bound UB, flags for
3037276479Sdim  // less/greater and for strict/non-strict comparison.
3038276479Sdim  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3039276479Sdim  //   var relational-op b
3040276479Sdim  //   b relational-op var
3041276479Sdim  //
3042276479Sdim  if (!S) {
3043276479Sdim    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var;
3044276479Sdim    return true;
3045276479Sdim  }
3046288943Sdim  S = getExprAsWritten(S);
3047276479Sdim  SourceLocation CondLoc = S->getLocStart();
3048276479Sdim  if (auto BO = dyn_cast<BinaryOperator>(S)) {
3049276479Sdim    if (BO->isRelationalOp()) {
3050276479Sdim      if (GetInitVarDecl(BO->getLHS()) == Var)
3051276479Sdim        return SetUB(BO->getRHS(),
3052276479Sdim                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3053276479Sdim                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3054276479Sdim                     BO->getSourceRange(), BO->getOperatorLoc());
3055276479Sdim      if (GetInitVarDecl(BO->getRHS()) == Var)
3056276479Sdim        return SetUB(BO->getLHS(),
3057276479Sdim                     (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3058276479Sdim                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3059276479Sdim                     BO->getSourceRange(), BO->getOperatorLoc());
3060276479Sdim    }
3061276479Sdim  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3062276479Sdim    if (CE->getNumArgs() == 2) {
3063276479Sdim      auto Op = CE->getOperator();
3064276479Sdim      switch (Op) {
3065276479Sdim      case OO_Greater:
3066276479Sdim      case OO_GreaterEqual:
3067276479Sdim      case OO_Less:
3068276479Sdim      case OO_LessEqual:
3069276479Sdim        if (GetInitVarDecl(CE->getArg(0)) == Var)
3070276479Sdim          return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3071276479Sdim                       Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3072276479Sdim                       CE->getOperatorLoc());
3073276479Sdim        if (GetInitVarDecl(CE->getArg(1)) == Var)
3074276479Sdim          return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3075276479Sdim                       Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3076276479Sdim                       CE->getOperatorLoc());
3077276479Sdim        break;
3078276479Sdim      default:
3079276479Sdim        break;
3080276479Sdim      }
3081276479Sdim    }
3082276479Sdim  }
3083276479Sdim  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3084276479Sdim      << S->getSourceRange() << Var;
3085276479Sdim  return true;
3086276479Sdim}
3087276479Sdim
3088276479Sdimbool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
3089276479Sdim  // RHS of canonical loop form increment can be:
3090276479Sdim  //   var + incr
3091276479Sdim  //   incr + var
3092276479Sdim  //   var - incr
3093276479Sdim  //
3094276479Sdim  RHS = RHS->IgnoreParenImpCasts();
3095276479Sdim  if (auto BO = dyn_cast<BinaryOperator>(RHS)) {
3096276479Sdim    if (BO->isAdditiveOp()) {
3097276479Sdim      bool IsAdd = BO->getOpcode() == BO_Add;
3098276479Sdim      if (GetInitVarDecl(BO->getLHS()) == Var)
3099276479Sdim        return SetStep(BO->getRHS(), !IsAdd);
3100276479Sdim      if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var)
3101276479Sdim        return SetStep(BO->getLHS(), false);
3102276479Sdim    }
3103276479Sdim  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3104276479Sdim    bool IsAdd = CE->getOperator() == OO_Plus;
3105276479Sdim    if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3106276479Sdim      if (GetInitVarDecl(CE->getArg(0)) == Var)
3107276479Sdim        return SetStep(CE->getArg(1), !IsAdd);
3108276479Sdim      if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var)
3109276479Sdim        return SetStep(CE->getArg(0), false);
3110276479Sdim    }
3111276479Sdim  }
3112276479Sdim  SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3113276479Sdim      << RHS->getSourceRange() << Var;
3114276479Sdim  return true;
3115276479Sdim}
3116276479Sdim
3117276479Sdimbool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
3118276479Sdim  // Check incr-expr for canonical loop form and return true if it
3119276479Sdim  // does not conform.
3120276479Sdim  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3121276479Sdim  //   ++var
3122276479Sdim  //   var++
3123276479Sdim  //   --var
3124276479Sdim  //   var--
3125276479Sdim  //   var += incr
3126276479Sdim  //   var -= incr
3127276479Sdim  //   var = var + incr
3128276479Sdim  //   var = incr + var
3129276479Sdim  //   var = var - incr
3130276479Sdim  //
3131276479Sdim  if (!S) {
3132276479Sdim    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var;
3133276479Sdim    return true;
3134276479Sdim  }
3135280031Sdim  IncrementSrcRange = S->getSourceRange();
3136276479Sdim  S = S->IgnoreParens();
3137276479Sdim  if (auto UO = dyn_cast<UnaryOperator>(S)) {
3138276479Sdim    if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var)
3139276479Sdim      return SetStep(
3140276479Sdim          SemaRef.ActOnIntegerConstant(UO->getLocStart(),
3141276479Sdim                                       (UO->isDecrementOp() ? -1 : 1)).get(),
3142276479Sdim          false);
3143276479Sdim  } else if (auto BO = dyn_cast<BinaryOperator>(S)) {
3144276479Sdim    switch (BO->getOpcode()) {
3145276479Sdim    case BO_AddAssign:
3146276479Sdim    case BO_SubAssign:
3147276479Sdim      if (GetInitVarDecl(BO->getLHS()) == Var)
3148276479Sdim        return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3149276479Sdim      break;
3150276479Sdim    case BO_Assign:
3151276479Sdim      if (GetInitVarDecl(BO->getLHS()) == Var)
3152276479Sdim        return CheckIncRHS(BO->getRHS());
3153276479Sdim      break;
3154276479Sdim    default:
3155276479Sdim      break;
3156276479Sdim    }
3157276479Sdim  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3158276479Sdim    switch (CE->getOperator()) {
3159276479Sdim    case OO_PlusPlus:
3160276479Sdim    case OO_MinusMinus:
3161276479Sdim      if (GetInitVarDecl(CE->getArg(0)) == Var)
3162276479Sdim        return SetStep(
3163276479Sdim            SemaRef.ActOnIntegerConstant(
3164276479Sdim                        CE->getLocStart(),
3165276479Sdim                        ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(),
3166276479Sdim            false);
3167276479Sdim      break;
3168276479Sdim    case OO_PlusEqual:
3169276479Sdim    case OO_MinusEqual:
3170276479Sdim      if (GetInitVarDecl(CE->getArg(0)) == Var)
3171276479Sdim        return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3172276479Sdim      break;
3173276479Sdim    case OO_Equal:
3174276479Sdim      if (GetInitVarDecl(CE->getArg(0)) == Var)
3175276479Sdim        return CheckIncRHS(CE->getArg(1));
3176276479Sdim      break;
3177276479Sdim    default:
3178276479Sdim      break;
3179276479Sdim    }
3180276479Sdim  }
3181276479Sdim  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3182276479Sdim      << S->getSourceRange() << Var;
3183276479Sdim  return true;
3184276479Sdim}
3185280031Sdim
3186288943Sdimnamespace {
3187288943Sdim// Transform variables declared in GNU statement expressions to new ones to
3188288943Sdim// avoid crash on codegen.
3189288943Sdimclass TransformToNewDefs : public TreeTransform<TransformToNewDefs> {
3190288943Sdim  typedef TreeTransform<TransformToNewDefs> BaseTransform;
3191288943Sdim
3192288943Sdimpublic:
3193288943Sdim  TransformToNewDefs(Sema &SemaRef) : BaseTransform(SemaRef) {}
3194288943Sdim
3195288943Sdim  Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
3196288943Sdim    if (auto *VD = cast<VarDecl>(D))
3197288943Sdim      if (!isa<ParmVarDecl>(D) && !isa<VarTemplateSpecializationDecl>(D) &&
3198288943Sdim          !isa<ImplicitParamDecl>(D)) {
3199288943Sdim        auto *NewVD = VarDecl::Create(
3200288943Sdim            SemaRef.Context, VD->getDeclContext(), VD->getLocStart(),
3201288943Sdim            VD->getLocation(), VD->getIdentifier(), VD->getType(),
3202288943Sdim            VD->getTypeSourceInfo(), VD->getStorageClass());
3203288943Sdim        NewVD->setTSCSpec(VD->getTSCSpec());
3204288943Sdim        NewVD->setInit(VD->getInit());
3205288943Sdim        NewVD->setInitStyle(VD->getInitStyle());
3206288943Sdim        NewVD->setExceptionVariable(VD->isExceptionVariable());
3207288943Sdim        NewVD->setNRVOVariable(VD->isNRVOVariable());
3208296417Sdim        NewVD->setCXXForRangeDecl(VD->isCXXForRangeDecl());
3209288943Sdim        NewVD->setConstexpr(VD->isConstexpr());
3210288943Sdim        NewVD->setInitCapture(VD->isInitCapture());
3211288943Sdim        NewVD->setPreviousDeclInSameBlockScope(
3212288943Sdim            VD->isPreviousDeclInSameBlockScope());
3213288943Sdim        VD->getDeclContext()->addHiddenDecl(NewVD);
3214296417Sdim        if (VD->hasAttrs())
3215296417Sdim          NewVD->setAttrs(VD->getAttrs());
3216288943Sdim        transformedLocalDecl(VD, NewVD);
3217288943Sdim        return NewVD;
3218288943Sdim      }
3219288943Sdim    return BaseTransform::TransformDefinition(Loc, D);
3220288943Sdim  }
3221288943Sdim
3222288943Sdim  ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
3223288943Sdim    if (auto *NewD = TransformDecl(E->getExprLoc(), E->getDecl()))
3224288943Sdim      if (E->getDecl() != NewD) {
3225288943Sdim        NewD->setReferenced();
3226288943Sdim        NewD->markUsed(SemaRef.Context);
3227288943Sdim        return DeclRefExpr::Create(
3228288943Sdim            SemaRef.Context, E->getQualifierLoc(), E->getTemplateKeywordLoc(),
3229288943Sdim            cast<ValueDecl>(NewD), E->refersToEnclosingVariableOrCapture(),
3230288943Sdim            E->getNameInfo(), E->getType(), E->getValueKind());
3231288943Sdim      }
3232288943Sdim    return BaseTransform::TransformDeclRefExpr(E);
3233288943Sdim  }
3234288943Sdim};
3235288943Sdim}
3236288943Sdim
3237280031Sdim/// \brief Build the expression to calculate the number of iterations.
3238280031SdimExpr *
3239280031SdimOpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
3240280031Sdim                                                const bool LimitedType) const {
3241288943Sdim  TransformToNewDefs Transform(SemaRef);
3242280031Sdim  ExprResult Diff;
3243288943Sdim  auto VarType = Var->getType().getNonReferenceType();
3244288943Sdim  if (VarType->isIntegerType() || VarType->isPointerType() ||
3245280031Sdim      SemaRef.getLangOpts().CPlusPlus) {
3246280031Sdim    // Upper - Lower
3247288943Sdim    auto *UBExpr = TestIsLessOp ? UB : LB;
3248288943Sdim    auto *LBExpr = TestIsLessOp ? LB : UB;
3249288943Sdim    Expr *Upper = Transform.TransformExpr(UBExpr).get();
3250288943Sdim    Expr *Lower = Transform.TransformExpr(LBExpr).get();
3251288943Sdim    if (!Upper || !Lower)
3252288943Sdim      return nullptr;
3253296417Sdim    if (!SemaRef.Context.hasSameType(Upper->getType(), UBExpr->getType())) {
3254296417Sdim      Upper = SemaRef
3255296417Sdim                  .PerformImplicitConversion(Upper, UBExpr->getType(),
3256296417Sdim                                             Sema::AA_Converting,
3257296417Sdim                                             /*AllowExplicit=*/true)
3258296417Sdim                  .get();
3259296417Sdim    }
3260296417Sdim    if (!SemaRef.Context.hasSameType(Lower->getType(), LBExpr->getType())) {
3261296417Sdim      Lower = SemaRef
3262296417Sdim                  .PerformImplicitConversion(Lower, LBExpr->getType(),
3263296417Sdim                                             Sema::AA_Converting,
3264296417Sdim                                             /*AllowExplicit=*/true)
3265296417Sdim                  .get();
3266296417Sdim    }
3267288943Sdim    if (!Upper || !Lower)
3268288943Sdim      return nullptr;
3269280031Sdim
3270280031Sdim    Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
3271280031Sdim
3272288943Sdim    if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
3273280031Sdim      // BuildBinOp already emitted error, this one is to point user to upper
3274280031Sdim      // and lower bound, and to tell what is passed to 'operator-'.
3275280031Sdim      SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
3276280031Sdim          << Upper->getSourceRange() << Lower->getSourceRange();
3277280031Sdim      return nullptr;
3278280031Sdim    }
3279280031Sdim  }
3280280031Sdim
3281280031Sdim  if (!Diff.isUsable())
3282280031Sdim    return nullptr;
3283280031Sdim
3284280031Sdim  // Upper - Lower [- 1]
3285280031Sdim  if (TestIsStrictOp)
3286280031Sdim    Diff = SemaRef.BuildBinOp(
3287280031Sdim        S, DefaultLoc, BO_Sub, Diff.get(),
3288280031Sdim        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3289280031Sdim  if (!Diff.isUsable())
3290280031Sdim    return nullptr;
3291280031Sdim
3292280031Sdim  // Upper - Lower [- 1] + Step
3293296417Sdim  auto *StepNoImp = Step->IgnoreImplicit();
3294296417Sdim  auto NewStep = Transform.TransformExpr(StepNoImp);
3295288943Sdim  if (NewStep.isInvalid())
3296288943Sdim    return nullptr;
3297296417Sdim  if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
3298296417Sdim                                   StepNoImp->getType())) {
3299296417Sdim    NewStep = SemaRef.PerformImplicitConversion(
3300296417Sdim        NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
3301296417Sdim        /*AllowExplicit=*/true);
3302296417Sdim    if (NewStep.isInvalid())
3303296417Sdim      return nullptr;
3304296417Sdim  }
3305288943Sdim  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
3306280031Sdim  if (!Diff.isUsable())
3307280031Sdim    return nullptr;
3308280031Sdim
3309280031Sdim  // Parentheses (for dumping/debugging purposes only).
3310280031Sdim  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
3311280031Sdim  if (!Diff.isUsable())
3312280031Sdim    return nullptr;
3313280031Sdim
3314280031Sdim  // (Upper - Lower [- 1] + Step) / Step
3315296417Sdim  NewStep = Transform.TransformExpr(StepNoImp);
3316288943Sdim  if (NewStep.isInvalid())
3317288943Sdim    return nullptr;
3318296417Sdim  if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
3319296417Sdim                                   StepNoImp->getType())) {
3320296417Sdim    NewStep = SemaRef.PerformImplicitConversion(
3321296417Sdim        NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
3322296417Sdim        /*AllowExplicit=*/true);
3323296417Sdim    if (NewStep.isInvalid())
3324296417Sdim      return nullptr;
3325296417Sdim  }
3326288943Sdim  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
3327280031Sdim  if (!Diff.isUsable())
3328280031Sdim    return nullptr;
3329280031Sdim
3330280031Sdim  // OpenMP runtime requires 32-bit or 64-bit loop variables.
3331288943Sdim  QualType Type = Diff.get()->getType();
3332288943Sdim  auto &C = SemaRef.Context;
3333288943Sdim  bool UseVarType = VarType->hasIntegerRepresentation() &&
3334288943Sdim                    C.getTypeSize(Type) > C.getTypeSize(VarType);
3335288943Sdim  if (!Type->isIntegerType() || UseVarType) {
3336288943Sdim    unsigned NewSize =
3337288943Sdim        UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
3338288943Sdim    bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3339288943Sdim                               : Type->hasSignedIntegerRepresentation();
3340288943Sdim    Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
3341296417Sdim    if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
3342296417Sdim      Diff = SemaRef.PerformImplicitConversion(
3343296417Sdim          Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
3344296417Sdim      if (!Diff.isUsable())
3345296417Sdim        return nullptr;
3346296417Sdim    }
3347288943Sdim  }
3348280031Sdim  if (LimitedType) {
3349280031Sdim    unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
3350280031Sdim    if (NewSize != C.getTypeSize(Type)) {
3351280031Sdim      if (NewSize < C.getTypeSize(Type)) {
3352280031Sdim        assert(NewSize == 64 && "incorrect loop var size");
3353280031Sdim        SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3354280031Sdim            << InitSrcRange << ConditionSrcRange;
3355280031Sdim      }
3356280031Sdim      QualType NewType = C.getIntTypeForBitwidth(
3357288943Sdim          NewSize, Type->hasSignedIntegerRepresentation() ||
3358288943Sdim                       C.getTypeSize(Type) < NewSize);
3359296417Sdim      if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
3360296417Sdim        Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
3361296417Sdim                                                 Sema::AA_Converting, true);
3362296417Sdim        if (!Diff.isUsable())
3363296417Sdim          return nullptr;
3364296417Sdim      }
3365280031Sdim    }
3366280031Sdim  }
3367280031Sdim
3368280031Sdim  return Diff.get();
3369280031Sdim}
3370280031Sdim
3371288943SdimExpr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const {
3372288943Sdim  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
3373288943Sdim  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
3374288943Sdim  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
3375288943Sdim  TransformToNewDefs Transform(SemaRef);
3376288943Sdim
3377288943Sdim  auto NewLB = Transform.TransformExpr(LB);
3378288943Sdim  auto NewUB = Transform.TransformExpr(UB);
3379288943Sdim  if (NewLB.isInvalid() || NewUB.isInvalid())
3380288943Sdim    return Cond;
3381296417Sdim  if (!SemaRef.Context.hasSameType(NewLB.get()->getType(), LB->getType())) {
3382296417Sdim    NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->getType(),
3383296417Sdim                                              Sema::AA_Converting,
3384296417Sdim                                              /*AllowExplicit=*/true);
3385296417Sdim  }
3386296417Sdim  if (!SemaRef.Context.hasSameType(NewUB.get()->getType(), UB->getType())) {
3387296417Sdim    NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->getType(),
3388296417Sdim                                              Sema::AA_Converting,
3389296417Sdim                                              /*AllowExplicit=*/true);
3390296417Sdim  }
3391288943Sdim  if (NewLB.isInvalid() || NewUB.isInvalid())
3392288943Sdim    return Cond;
3393288943Sdim  auto CondExpr = SemaRef.BuildBinOp(
3394288943Sdim      S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
3395288943Sdim                                  : (TestIsStrictOp ? BO_GT : BO_GE),
3396288943Sdim      NewLB.get(), NewUB.get());
3397288943Sdim  if (CondExpr.isUsable()) {
3398296417Sdim    if (!SemaRef.Context.hasSameType(CondExpr.get()->getType(),
3399296417Sdim                                     SemaRef.Context.BoolTy))
3400296417Sdim      CondExpr = SemaRef.PerformImplicitConversion(
3401296417Sdim          CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
3402296417Sdim          /*AllowExplicit=*/true);
3403288943Sdim  }
3404288943Sdim  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
3405288943Sdim  // Otherwise use original loop conditon and evaluate it in runtime.
3406288943Sdim  return CondExpr.isUsable() ? CondExpr.get() : Cond;
3407288943Sdim}
3408288943Sdim
3409280031Sdim/// \brief Build reference expression to the counter be used for codegen.
3410280031SdimExpr *OpenMPIterationSpaceChecker::BuildCounterVar() const {
3411296417Sdim  return buildDeclRefExpr(SemaRef, Var, Var->getType().getNonReferenceType(),
3412296417Sdim                          DefaultLoc);
3413280031Sdim}
3414280031Sdim
3415296417SdimExpr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
3416296417Sdim  if (Var && !Var->isInvalidDecl()) {
3417296417Sdim    auto Type = Var->getType().getNonReferenceType();
3418296417Sdim    auto *PrivateVar =
3419296417Sdim        buildVarDecl(SemaRef, DefaultLoc, Type, Var->getName(),
3420296417Sdim                     Var->hasAttrs() ? &Var->getAttrs() : nullptr);
3421296417Sdim    if (PrivateVar->isInvalidDecl())
3422296417Sdim      return nullptr;
3423296417Sdim    return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
3424296417Sdim  }
3425296417Sdim  return nullptr;
3426296417Sdim}
3427296417Sdim
3428280031Sdim/// \brief Build initization of the counter be used for codegen.
3429280031SdimExpr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; }
3430280031Sdim
3431280031Sdim/// \brief Build step of the counter be used for codegen.
3432280031SdimExpr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
3433280031Sdim
3434280031Sdim/// \brief Iteration space of a single for loop.
3435280031Sdimstruct LoopIterationSpace {
3436288943Sdim  /// \brief Condition of the loop.
3437288943Sdim  Expr *PreCond;
3438280031Sdim  /// \brief This expression calculates the number of iterations in the loop.
3439280031Sdim  /// It is always possible to calculate it before starting the loop.
3440280031Sdim  Expr *NumIterations;
3441280031Sdim  /// \brief The loop counter variable.
3442280031Sdim  Expr *CounterVar;
3443296417Sdim  /// \brief Private loop counter variable.
3444296417Sdim  Expr *PrivateCounterVar;
3445280031Sdim  /// \brief This is initializer for the initial value of #CounterVar.
3446280031Sdim  Expr *CounterInit;
3447280031Sdim  /// \brief This is step for the #CounterVar used to generate its update:
3448280031Sdim  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
3449280031Sdim  Expr *CounterStep;
3450280031Sdim  /// \brief Should step be subtracted?
3451280031Sdim  bool Subtract;
3452280031Sdim  /// \brief Source range of the loop init.
3453280031Sdim  SourceRange InitSrcRange;
3454280031Sdim  /// \brief Source range of the loop condition.
3455280031Sdim  SourceRange CondSrcRange;
3456280031Sdim  /// \brief Source range of the loop increment.
3457280031Sdim  SourceRange IncSrcRange;
3458280031Sdim};
3459280031Sdim
3460276479Sdim} // namespace
3461276479Sdim
3462288943Sdimvoid Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
3463288943Sdim  assert(getLangOpts().OpenMP && "OpenMP is not active.");
3464288943Sdim  assert(Init && "Expected loop in canonical form.");
3465296417Sdim  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
3466296417Sdim  if (AssociatedLoops > 0 &&
3467288943Sdim      isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
3468288943Sdim    OpenMPIterationSpaceChecker ISC(*this, ForLoc);
3469296417Sdim    if (!ISC.CheckInit(Init, /*EmitDiags=*/false))
3470288943Sdim      DSAStack->addLoopControlVariable(ISC.GetLoopVar());
3471296417Sdim    DSAStack->setAssociatedLoops(AssociatedLoops - 1);
3472288943Sdim  }
3473288943Sdim}
3474288943Sdim
3475276479Sdim/// \brief Called on a for stmt to check and extract its iteration space
3476276479Sdim/// for further processing (such as collapsing).
3477276479Sdimstatic bool CheckOpenMPIterationSpace(
3478276479Sdim    OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
3479276479Sdim    unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
3480296417Sdim    Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
3481280031Sdim    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
3482280031Sdim    LoopIterationSpace &ResultIterSpace) {
3483276479Sdim  // OpenMP [2.6, Canonical Loop Form]
3484276479Sdim  //   for (init-expr; test-expr; incr-expr) structured-block
3485276479Sdim  auto For = dyn_cast_or_null<ForStmt>(S);
3486276479Sdim  if (!For) {
3487276479Sdim    SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
3488296417Sdim        << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
3489296417Sdim        << getOpenMPDirectiveName(DKind) << NestedLoopCount
3490296417Sdim        << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
3491296417Sdim    if (NestedLoopCount > 1) {
3492296417Sdim      if (CollapseLoopCountExpr && OrderedLoopCountExpr)
3493296417Sdim        SemaRef.Diag(DSA.getConstructLoc(),
3494296417Sdim                     diag::note_omp_collapse_ordered_expr)
3495296417Sdim            << 2 << CollapseLoopCountExpr->getSourceRange()
3496296417Sdim            << OrderedLoopCountExpr->getSourceRange();
3497296417Sdim      else if (CollapseLoopCountExpr)
3498296417Sdim        SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
3499296417Sdim                     diag::note_omp_collapse_ordered_expr)
3500296417Sdim            << 0 << CollapseLoopCountExpr->getSourceRange();
3501296417Sdim      else
3502296417Sdim        SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
3503296417Sdim                     diag::note_omp_collapse_ordered_expr)
3504296417Sdim            << 1 << OrderedLoopCountExpr->getSourceRange();
3505296417Sdim    }
3506276479Sdim    return true;
3507276479Sdim  }
3508276479Sdim  assert(For->getBody());
3509276479Sdim
3510276479Sdim  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
3511276479Sdim
3512276479Sdim  // Check init.
3513276479Sdim  auto Init = For->getInit();
3514276479Sdim  if (ISC.CheckInit(Init)) {
3515276479Sdim    return true;
3516276479Sdim  }
3517276479Sdim
3518276479Sdim  bool HasErrors = false;
3519276479Sdim
3520276479Sdim  // Check loop variable's type.
3521276479Sdim  auto Var = ISC.GetLoopVar();
3522276479Sdim
3523276479Sdim  // OpenMP [2.6, Canonical Loop Form]
3524276479Sdim  // Var is one of the following:
3525276479Sdim  //   A variable of signed or unsigned integer type.
3526276479Sdim  //   For C++, a variable of a random access iterator type.
3527276479Sdim  //   For C, a variable of a pointer type.
3528296417Sdim  auto VarType = Var->getType().getNonReferenceType();
3529276479Sdim  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
3530276479Sdim      !VarType->isPointerType() &&
3531276479Sdim      !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
3532276479Sdim    SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
3533276479Sdim        << SemaRef.getLangOpts().CPlusPlus;
3534276479Sdim    HasErrors = true;
3535276479Sdim  }
3536276479Sdim
3537276479Sdim  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a
3538276479Sdim  // Construct
3539276479Sdim  // The loop iteration variable(s) in the associated for-loop(s) of a for or
3540276479Sdim  // parallel for construct is (are) private.
3541276479Sdim  // The loop iteration variable in the associated for-loop of a simd construct
3542276479Sdim  // with just one associated for-loop is linear with a constant-linear-step
3543276479Sdim  // that is the increment of the associated for-loop.
3544276479Sdim  // Exclude loop var from the list of variables with implicitly defined data
3545276479Sdim  // sharing attributes.
3546280031Sdim  VarsWithImplicitDSA.erase(Var);
3547276479Sdim
3548276479Sdim  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in
3549276479Sdim  // a Construct, C/C++].
3550276479Sdim  // The loop iteration variable in the associated for-loop of a simd construct
3551276479Sdim  // with just one associated for-loop may be listed in a linear clause with a
3552276479Sdim  // constant-linear-step that is the increment of the associated for-loop.
3553276479Sdim  // The loop iteration variable(s) in the associated for-loop(s) of a for or
3554276479Sdim  // parallel for construct may be listed in a private or lastprivate clause.
3555276479Sdim  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false);
3556280031Sdim  auto LoopVarRefExpr = ISC.GetLoopVarRefExpr();
3557280031Sdim  // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
3558280031Sdim  // declared in the loop and it is predetermined as a private.
3559276479Sdim  auto PredeterminedCKind =
3560276479Sdim      isOpenMPSimdDirective(DKind)
3561276479Sdim          ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
3562276479Sdim          : OMPC_private;
3563276479Sdim  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
3564296417Sdim        DVar.CKind != PredeterminedCKind) ||
3565296417Sdim       ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
3566296417Sdim         isOpenMPDistributeDirective(DKind)) &&
3567296417Sdim        !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
3568296417Sdim        DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
3569296417Sdim      (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
3570276479Sdim    SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
3571276479Sdim        << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
3572276479Sdim        << getOpenMPClauseName(PredeterminedCKind);
3573288943Sdim    if (DVar.RefExpr == nullptr)
3574288943Sdim      DVar.CKind = PredeterminedCKind;
3575288943Sdim    ReportOriginalDSA(SemaRef, &DSA, Var, DVar, /*IsLoopIterVar=*/true);
3576276479Sdim    HasErrors = true;
3577280031Sdim  } else if (LoopVarRefExpr != nullptr) {
3578276479Sdim    // Make the loop iteration variable private (for worksharing constructs),
3579276479Sdim    // linear (for simd directives with the only one associated loop) or
3580296417Sdim    // lastprivate (for simd directives with several collapsed or ordered
3581296417Sdim    // loops).
3582280031Sdim    if (DVar.CKind == OMPC_unknown)
3583280031Sdim      DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(),
3584280031Sdim                        /*FromParent=*/false);
3585288943Sdim    DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind);
3586276479Sdim  }
3587276479Sdim
3588276479Sdim  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
3589276479Sdim
3590276479Sdim  // Check test-expr.
3591276479Sdim  HasErrors |= ISC.CheckCond(For->getCond());
3592276479Sdim
3593276479Sdim  // Check incr-expr.
3594276479Sdim  HasErrors |= ISC.CheckInc(For->getInc());
3595276479Sdim
3596280031Sdim  if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
3597276479Sdim    return HasErrors;
3598276479Sdim
3599280031Sdim  // Build the loop's iteration space representation.
3600288943Sdim  ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond());
3601280031Sdim  ResultIterSpace.NumIterations = ISC.BuildNumIterations(
3602296417Sdim      DSA.getCurScope(), (isOpenMPWorksharingDirective(DKind) ||
3603296417Sdim                          isOpenMPTaskLoopDirective(DKind) ||
3604296417Sdim                          isOpenMPDistributeDirective(DKind)));
3605280031Sdim  ResultIterSpace.CounterVar = ISC.BuildCounterVar();
3606296417Sdim  ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
3607280031Sdim  ResultIterSpace.CounterInit = ISC.BuildCounterInit();
3608280031Sdim  ResultIterSpace.CounterStep = ISC.BuildCounterStep();
3609280031Sdim  ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
3610280031Sdim  ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
3611280031Sdim  ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
3612280031Sdim  ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
3613280031Sdim
3614288943Sdim  HasErrors |= (ResultIterSpace.PreCond == nullptr ||
3615288943Sdim                ResultIterSpace.NumIterations == nullptr ||
3616280031Sdim                ResultIterSpace.CounterVar == nullptr ||
3617296417Sdim                ResultIterSpace.PrivateCounterVar == nullptr ||
3618280031Sdim                ResultIterSpace.CounterInit == nullptr ||
3619280031Sdim                ResultIterSpace.CounterStep == nullptr);
3620280031Sdim
3621276479Sdim  return HasErrors;
3622276479Sdim}
3623276479Sdim
3624288943Sdim/// \brief Build 'VarRef = Start.
3625288943Sdimstatic ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc,
3626288943Sdim                                   ExprResult VarRef, ExprResult Start) {
3627288943Sdim  TransformToNewDefs Transform(SemaRef);
3628288943Sdim  // Build 'VarRef = Start.
3629296417Sdim  auto *StartNoImp = Start.get()->IgnoreImplicit();
3630296417Sdim  auto NewStart = Transform.TransformExpr(StartNoImp);
3631288943Sdim  if (NewStart.isInvalid())
3632288943Sdim    return ExprError();
3633296417Sdim  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
3634296417Sdim                                   StartNoImp->getType())) {
3635296417Sdim    NewStart = SemaRef.PerformImplicitConversion(
3636296417Sdim        NewStart.get(), StartNoImp->getType(), Sema::AA_Converting,
3637296417Sdim        /*AllowExplicit=*/true);
3638296417Sdim    if (NewStart.isInvalid())
3639296417Sdim      return ExprError();
3640296417Sdim  }
3641296417Sdim  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
3642296417Sdim                                   VarRef.get()->getType())) {
3643296417Sdim    NewStart = SemaRef.PerformImplicitConversion(
3644296417Sdim        NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
3645296417Sdim        /*AllowExplicit=*/true);
3646296417Sdim    if (!NewStart.isUsable())
3647296417Sdim      return ExprError();
3648296417Sdim  }
3649288943Sdim
3650288943Sdim  auto Init =
3651288943Sdim      SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
3652288943Sdim  return Init;
3653276479Sdim}
3654276479Sdim
3655280031Sdim/// \brief Build 'VarRef = Start + Iter * Step'.
3656280031Sdimstatic ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S,
3657280031Sdim                                     SourceLocation Loc, ExprResult VarRef,
3658280031Sdim                                     ExprResult Start, ExprResult Iter,
3659280031Sdim                                     ExprResult Step, bool Subtract) {
3660280031Sdim  // Add parentheses (for debugging purposes only).
3661280031Sdim  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
3662280031Sdim  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
3663280031Sdim      !Step.isUsable())
3664280031Sdim    return ExprError();
3665280031Sdim
3666296417Sdim  auto *StepNoImp = Step.get()->IgnoreImplicit();
3667288943Sdim  TransformToNewDefs Transform(SemaRef);
3668296417Sdim  auto NewStep = Transform.TransformExpr(StepNoImp);
3669288943Sdim  if (NewStep.isInvalid())
3670288943Sdim    return ExprError();
3671296417Sdim  if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
3672296417Sdim                                   StepNoImp->getType())) {
3673296417Sdim    NewStep = SemaRef.PerformImplicitConversion(
3674296417Sdim        NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
3675296417Sdim        /*AllowExplicit=*/true);
3676296417Sdim    if (NewStep.isInvalid())
3677296417Sdim      return ExprError();
3678296417Sdim  }
3679288943Sdim  ExprResult Update =
3680288943Sdim      SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
3681280031Sdim  if (!Update.isUsable())
3682280031Sdim    return ExprError();
3683280031Sdim
3684280031Sdim  // Build 'VarRef = Start + Iter * Step'.
3685296417Sdim  auto *StartNoImp = Start.get()->IgnoreImplicit();
3686296417Sdim  auto NewStart = Transform.TransformExpr(StartNoImp);
3687288943Sdim  if (NewStart.isInvalid())
3688288943Sdim    return ExprError();
3689296417Sdim  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
3690296417Sdim                                   StartNoImp->getType())) {
3691296417Sdim    NewStart = SemaRef.PerformImplicitConversion(
3692296417Sdim        NewStart.get(), StartNoImp->getType(), Sema::AA_Converting,
3693296417Sdim        /*AllowExplicit=*/true);
3694296417Sdim    if (NewStart.isInvalid())
3695296417Sdim      return ExprError();
3696296417Sdim  }
3697280031Sdim  Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add),
3698288943Sdim                              NewStart.get(), Update.get());
3699280031Sdim  if (!Update.isUsable())
3700280031Sdim    return ExprError();
3701280031Sdim
3702280031Sdim  Update = SemaRef.PerformImplicitConversion(
3703280031Sdim      Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
3704280031Sdim  if (!Update.isUsable())
3705280031Sdim    return ExprError();
3706280031Sdim
3707280031Sdim  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
3708280031Sdim  return Update;
3709280031Sdim}
3710280031Sdim
3711280031Sdim/// \brief Convert integer expression \a E to make it have at least \a Bits
3712280031Sdim/// bits.
3713280031Sdimstatic ExprResult WidenIterationCount(unsigned Bits, Expr *E,
3714280031Sdim                                      Sema &SemaRef) {
3715280031Sdim  if (E == nullptr)
3716280031Sdim    return ExprError();
3717280031Sdim  auto &C = SemaRef.Context;
3718280031Sdim  QualType OldType = E->getType();
3719280031Sdim  unsigned HasBits = C.getTypeSize(OldType);
3720280031Sdim  if (HasBits >= Bits)
3721280031Sdim    return ExprResult(E);
3722280031Sdim  // OK to convert to signed, because new type has more bits than old.
3723280031Sdim  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
3724280031Sdim  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
3725280031Sdim                                           true);
3726280031Sdim}
3727280031Sdim
3728280031Sdim/// \brief Check if the given expression \a E is a constant integer that fits
3729280031Sdim/// into \a Bits bits.
3730280031Sdimstatic bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
3731280031Sdim  if (E == nullptr)
3732280031Sdim    return false;
3733280031Sdim  llvm::APSInt Result;
3734280031Sdim  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
3735280031Sdim    return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
3736280031Sdim  return false;
3737280031Sdim}
3738280031Sdim
3739276479Sdim/// \brief Called on a for stmt to check itself and nested loops (if any).
3740276479Sdim/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
3741276479Sdim/// number of collapsed loops otherwise.
3742276479Sdimstatic unsigned
3743296417SdimCheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
3744296417Sdim                Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
3745296417Sdim                DSAStackTy &DSA,
3746280031Sdim                llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
3747280031Sdim                OMPLoopDirective::HelperExprs &Built) {
3748276479Sdim  unsigned NestedLoopCount = 1;
3749296417Sdim  if (CollapseLoopCountExpr) {
3750276479Sdim    // Found 'collapse' clause - calculate collapse number.
3751276479Sdim    llvm::APSInt Result;
3752296417Sdim    if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
3753276479Sdim      NestedLoopCount = Result.getLimitedValue();
3754276479Sdim  }
3755296417Sdim  if (OrderedLoopCountExpr) {
3756296417Sdim    // Found 'ordered' clause - calculate collapse number.
3757296417Sdim    llvm::APSInt Result;
3758296417Sdim    if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
3759296417Sdim      if (Result.getLimitedValue() < NestedLoopCount) {
3760296417Sdim        SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
3761296417Sdim                     diag::err_omp_wrong_ordered_loop_count)
3762296417Sdim            << OrderedLoopCountExpr->getSourceRange();
3763296417Sdim        SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
3764296417Sdim                     diag::note_collapse_loop_count)
3765296417Sdim            << CollapseLoopCountExpr->getSourceRange();
3766296417Sdim      }
3767296417Sdim      NestedLoopCount = Result.getLimitedValue();
3768296417Sdim    }
3769296417Sdim  }
3770276479Sdim  // This is helper routine for loop directives (e.g., 'for', 'simd',
3771276479Sdim  // 'for simd', etc.).
3772280031Sdim  SmallVector<LoopIterationSpace, 4> IterSpaces;
3773280031Sdim  IterSpaces.resize(NestedLoopCount);
3774280031Sdim  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
3775276479Sdim  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
3776276479Sdim    if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
3777296417Sdim                                  NestedLoopCount, CollapseLoopCountExpr,
3778296417Sdim                                  OrderedLoopCountExpr, VarsWithImplicitDSA,
3779296417Sdim                                  IterSpaces[Cnt]))
3780276479Sdim      return 0;
3781276479Sdim    // Move on to the next nested for loop, or to the loop body.
3782280031Sdim    // OpenMP [2.8.1, simd construct, Restrictions]
3783280031Sdim    // All loops associated with the construct must be perfectly nested; that
3784280031Sdim    // is, there must be no intervening code nor any OpenMP directive between
3785280031Sdim    // any two loops.
3786280031Sdim    CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
3787276479Sdim  }
3788276479Sdim
3789280031Sdim  Built.clear(/* size */ NestedLoopCount);
3790280031Sdim
3791280031Sdim  if (SemaRef.CurContext->isDependentContext())
3792280031Sdim    return NestedLoopCount;
3793280031Sdim
3794280031Sdim  // An example of what is generated for the following code:
3795280031Sdim  //
3796296417Sdim  //   #pragma omp simd collapse(2) ordered(2)
3797280031Sdim  //   for (i = 0; i < NI; ++i)
3798296417Sdim  //     for (k = 0; k < NK; ++k)
3799296417Sdim  //       for (j = J0; j < NJ; j+=2) {
3800296417Sdim  //         <loop body>
3801296417Sdim  //       }
3802280031Sdim  //
3803280031Sdim  // We generate the code below.
3804280031Sdim  // Note: the loop body may be outlined in CodeGen.
3805280031Sdim  // Note: some counters may be C++ classes, operator- is used to find number of
3806280031Sdim  // iterations and operator+= to calculate counter value.
3807280031Sdim  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
3808280031Sdim  // or i64 is currently supported).
3809280031Sdim  //
3810280031Sdim  //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
3811280031Sdim  //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
3812280031Sdim  //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
3813280031Sdim  //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
3814280031Sdim  //     // similar updates for vars in clauses (e.g. 'linear')
3815280031Sdim  //     <loop body (using local i and j)>
3816280031Sdim  //   }
3817280031Sdim  //   i = NI; // assign final values of counters
3818280031Sdim  //   j = NJ;
3819280031Sdim  //
3820280031Sdim
3821280031Sdim  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
3822280031Sdim  // the iteration counts of the collapsed for loops.
3823288943Sdim  // Precondition tests if there is at least one iteration (all conditions are
3824288943Sdim  // true).
3825288943Sdim  auto PreCond = ExprResult(IterSpaces[0].PreCond);
3826280031Sdim  auto N0 = IterSpaces[0].NumIterations;
3827288943Sdim  ExprResult LastIteration32 = WidenIterationCount(
3828288943Sdim      32 /* Bits */, SemaRef.PerformImplicitConversion(
3829288943Sdim                                N0->IgnoreImpCasts(), N0->getType(),
3830288943Sdim                                Sema::AA_Converting, /*AllowExplicit=*/true)
3831288943Sdim                         .get(),
3832288943Sdim      SemaRef);
3833288943Sdim  ExprResult LastIteration64 = WidenIterationCount(
3834288943Sdim      64 /* Bits */, SemaRef.PerformImplicitConversion(
3835288943Sdim                                N0->IgnoreImpCasts(), N0->getType(),
3836288943Sdim                                Sema::AA_Converting, /*AllowExplicit=*/true)
3837288943Sdim                         .get(),
3838288943Sdim      SemaRef);
3839280031Sdim
3840280031Sdim  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
3841280031Sdim    return NestedLoopCount;
3842280031Sdim
3843280031Sdim  auto &C = SemaRef.Context;
3844280031Sdim  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
3845280031Sdim
3846280031Sdim  Scope *CurScope = DSA.getCurScope();
3847280031Sdim  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
3848288943Sdim    if (PreCond.isUsable()) {
3849288943Sdim      PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd,
3850288943Sdim                                   PreCond.get(), IterSpaces[Cnt].PreCond);
3851288943Sdim    }
3852280031Sdim    auto N = IterSpaces[Cnt].NumIterations;
3853280031Sdim    AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
3854280031Sdim    if (LastIteration32.isUsable())
3855288943Sdim      LastIteration32 = SemaRef.BuildBinOp(
3856288943Sdim          CurScope, SourceLocation(), BO_Mul, LastIteration32.get(),
3857288943Sdim          SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
3858288943Sdim                                            Sema::AA_Converting,
3859288943Sdim                                            /*AllowExplicit=*/true)
3860288943Sdim              .get());
3861280031Sdim    if (LastIteration64.isUsable())
3862288943Sdim      LastIteration64 = SemaRef.BuildBinOp(
3863288943Sdim          CurScope, SourceLocation(), BO_Mul, LastIteration64.get(),
3864288943Sdim          SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
3865288943Sdim                                            Sema::AA_Converting,
3866288943Sdim                                            /*AllowExplicit=*/true)
3867288943Sdim              .get());
3868280031Sdim  }
3869280031Sdim
3870280031Sdim  // Choose either the 32-bit or 64-bit version.
3871280031Sdim  ExprResult LastIteration = LastIteration64;
3872280031Sdim  if (LastIteration32.isUsable() &&
3873280031Sdim      C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
3874280031Sdim      (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
3875280031Sdim       FitsInto(
3876280031Sdim           32 /* Bits */,
3877280031Sdim           LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
3878280031Sdim           LastIteration64.get(), SemaRef)))
3879280031Sdim    LastIteration = LastIteration32;
3880280031Sdim
3881280031Sdim  if (!LastIteration.isUsable())
3882280031Sdim    return 0;
3883280031Sdim
3884280031Sdim  // Save the number of iterations.
3885280031Sdim  ExprResult NumIterations = LastIteration;
3886280031Sdim  {
3887280031Sdim    LastIteration = SemaRef.BuildBinOp(
3888280031Sdim        CurScope, SourceLocation(), BO_Sub, LastIteration.get(),
3889280031Sdim        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3890280031Sdim    if (!LastIteration.isUsable())
3891280031Sdim      return 0;
3892280031Sdim  }
3893280031Sdim
3894280031Sdim  // Calculate the last iteration number beforehand instead of doing this on
3895280031Sdim  // each iteration. Do not do this if the number of iterations may be kfold-ed.
3896280031Sdim  llvm::APSInt Result;
3897280031Sdim  bool IsConstant =
3898280031Sdim      LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
3899280031Sdim  ExprResult CalcLastIteration;
3900280031Sdim  if (!IsConstant) {
3901280031Sdim    SourceLocation SaveLoc;
3902280031Sdim    VarDecl *SaveVar =
3903288943Sdim        buildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(),
3904280031Sdim                     ".omp.last.iteration");
3905288943Sdim    ExprResult SaveRef = buildDeclRefExpr(
3906288943Sdim        SemaRef, SaveVar, LastIteration.get()->getType(), SaveLoc);
3907280031Sdim    CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign,
3908280031Sdim                                           SaveRef.get(), LastIteration.get());
3909280031Sdim    LastIteration = SaveRef;
3910280031Sdim
3911280031Sdim    // Prepare SaveRef + 1.
3912280031Sdim    NumIterations = SemaRef.BuildBinOp(
3913280031Sdim        CurScope, SaveLoc, BO_Add, SaveRef.get(),
3914280031Sdim        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3915280031Sdim    if (!NumIterations.isUsable())
3916280031Sdim      return 0;
3917280031Sdim  }
3918280031Sdim
3919280031Sdim  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
3920280031Sdim
3921280031Sdim  QualType VType = LastIteration.get()->getType();
3922280031Sdim  // Build variables passed into runtime, nesessary for worksharing directives.
3923280031Sdim  ExprResult LB, UB, IL, ST, EUB;
3924296417Sdim  if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
3925296417Sdim      isOpenMPDistributeDirective(DKind)) {
3926280031Sdim    // Lower bound variable, initialized with zero.
3927288943Sdim    VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
3928288943Sdim    LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
3929280031Sdim    SemaRef.AddInitializerToDecl(
3930280031Sdim        LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
3931280031Sdim        /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
3932280031Sdim
3933280031Sdim    // Upper bound variable, initialized with last iteration number.
3934288943Sdim    VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
3935288943Sdim    UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
3936280031Sdim    SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
3937280031Sdim                                 /*DirectInit*/ false,
3938280031Sdim                                 /*TypeMayContainAuto*/ false);
3939280031Sdim
3940280031Sdim    // A 32-bit variable-flag where runtime returns 1 for the last iteration.
3941280031Sdim    // This will be used to implement clause 'lastprivate'.
3942280031Sdim    QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
3943288943Sdim    VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
3944288943Sdim    IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
3945280031Sdim    SemaRef.AddInitializerToDecl(
3946280031Sdim        ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
3947280031Sdim        /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
3948280031Sdim
3949280031Sdim    // Stride variable returned by runtime (we initialize it to 1 by default).
3950288943Sdim    VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride");
3951288943Sdim    ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc);
3952280031Sdim    SemaRef.AddInitializerToDecl(
3953280031Sdim        STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
3954280031Sdim        /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
3955280031Sdim
3956280031Sdim    // Build expression: UB = min(UB, LastIteration)
3957280031Sdim    // It is nesessary for CodeGen of directives with static scheduling.
3958280031Sdim    ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
3959280031Sdim                                                UB.get(), LastIteration.get());
3960280031Sdim    ExprResult CondOp = SemaRef.ActOnConditionalOp(
3961280031Sdim        InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
3962280031Sdim    EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
3963280031Sdim                             CondOp.get());
3964280031Sdim    EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
3965280031Sdim  }
3966280031Sdim
3967280031Sdim  // Build the iteration variable and its initialization before loop.
3968280031Sdim  ExprResult IV;
3969280031Sdim  ExprResult Init;
3970280031Sdim  {
3971288943Sdim    VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv");
3972288943Sdim    IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc);
3973296417Sdim    Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
3974296417Sdim                 isOpenMPTaskLoopDirective(DKind) ||
3975296417Sdim                 isOpenMPDistributeDirective(DKind))
3976280031Sdim                    ? LB.get()
3977280031Sdim                    : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
3978280031Sdim    Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
3979280031Sdim    Init = SemaRef.ActOnFinishFullExpr(Init.get());
3980280031Sdim  }
3981280031Sdim
3982280031Sdim  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
3983280031Sdim  SourceLocation CondLoc;
3984280031Sdim  ExprResult Cond =
3985296417Sdim      (isOpenMPWorksharingDirective(DKind) ||
3986296417Sdim       isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
3987280031Sdim          ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
3988280031Sdim          : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
3989280031Sdim                               NumIterations.get());
3990280031Sdim
3991280031Sdim  // Loop increment (IV = IV + 1)
3992280031Sdim  SourceLocation IncLoc;
3993280031Sdim  ExprResult Inc =
3994280031Sdim      SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
3995280031Sdim                         SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
3996280031Sdim  if (!Inc.isUsable())
3997280031Sdim    return 0;
3998280031Sdim  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
3999280031Sdim  Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
4000280031Sdim  if (!Inc.isUsable())
4001280031Sdim    return 0;
4002280031Sdim
4003280031Sdim  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
4004280031Sdim  // Used for directives with static scheduling.
4005280031Sdim  ExprResult NextLB, NextUB;
4006296417Sdim  if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
4007296417Sdim      isOpenMPDistributeDirective(DKind)) {
4008280031Sdim    // LB + ST
4009280031Sdim    NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
4010280031Sdim    if (!NextLB.isUsable())
4011280031Sdim      return 0;
4012280031Sdim    // LB = LB + ST
4013280031Sdim    NextLB =
4014280031Sdim        SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
4015280031Sdim    NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
4016280031Sdim    if (!NextLB.isUsable())
4017280031Sdim      return 0;
4018280031Sdim    // UB + ST
4019280031Sdim    NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
4020280031Sdim    if (!NextUB.isUsable())
4021280031Sdim      return 0;
4022280031Sdim    // UB = UB + ST
4023280031Sdim    NextUB =
4024280031Sdim        SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
4025280031Sdim    NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
4026280031Sdim    if (!NextUB.isUsable())
4027280031Sdim      return 0;
4028280031Sdim  }
4029280031Sdim
4030280031Sdim  // Build updates and final values of the loop counters.
4031280031Sdim  bool HasErrors = false;
4032280031Sdim  Built.Counters.resize(NestedLoopCount);
4033288943Sdim  Built.Inits.resize(NestedLoopCount);
4034280031Sdim  Built.Updates.resize(NestedLoopCount);
4035280031Sdim  Built.Finals.resize(NestedLoopCount);
4036280031Sdim  {
4037280031Sdim    ExprResult Div;
4038280031Sdim    // Go from inner nested loop to outer.
4039280031Sdim    for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4040280031Sdim      LoopIterationSpace &IS = IterSpaces[Cnt];
4041280031Sdim      SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
4042280031Sdim      // Build: Iter = (IV / Div) % IS.NumIters
4043280031Sdim      // where Div is product of previous iterations' IS.NumIters.
4044280031Sdim      ExprResult Iter;
4045280031Sdim      if (Div.isUsable()) {
4046280031Sdim        Iter =
4047280031Sdim            SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
4048280031Sdim      } else {
4049280031Sdim        Iter = IV;
4050280031Sdim        assert((Cnt == (int)NestedLoopCount - 1) &&
4051280031Sdim               "unusable div expected on first iteration only");
4052280031Sdim      }
4053280031Sdim
4054280031Sdim      if (Cnt != 0 && Iter.isUsable())
4055280031Sdim        Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
4056280031Sdim                                  IS.NumIterations);
4057280031Sdim      if (!Iter.isUsable()) {
4058280031Sdim        HasErrors = true;
4059280031Sdim        break;
4060280031Sdim      }
4061280031Sdim
4062288943Sdim      // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
4063288943Sdim      auto *CounterVar = buildDeclRefExpr(
4064288943Sdim          SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()),
4065288943Sdim          IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
4066288943Sdim          /*RefersToCapture=*/true);
4067288943Sdim      ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
4068288943Sdim                                         IS.CounterInit);
4069288943Sdim      if (!Init.isUsable()) {
4070288943Sdim        HasErrors = true;
4071288943Sdim        break;
4072288943Sdim      }
4073280031Sdim      ExprResult Update =
4074288943Sdim          BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
4075280031Sdim                             IS.CounterInit, Iter, IS.CounterStep, IS.Subtract);
4076280031Sdim      if (!Update.isUsable()) {
4077280031Sdim        HasErrors = true;
4078280031Sdim        break;
4079280031Sdim      }
4080280031Sdim
4081280031Sdim      // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
4082280031Sdim      ExprResult Final = BuildCounterUpdate(
4083288943Sdim          SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4084280031Sdim          IS.NumIterations, IS.CounterStep, IS.Subtract);
4085280031Sdim      if (!Final.isUsable()) {
4086280031Sdim        HasErrors = true;
4087280031Sdim        break;
4088280031Sdim      }
4089280031Sdim
4090280031Sdim      // Build Div for the next iteration: Div <- Div * IS.NumIters
4091280031Sdim      if (Cnt != 0) {
4092280031Sdim        if (Div.isUnset())
4093280031Sdim          Div = IS.NumIterations;
4094280031Sdim        else
4095280031Sdim          Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
4096280031Sdim                                   IS.NumIterations);
4097280031Sdim
4098280031Sdim        // Add parentheses (for debugging purposes only).
4099280031Sdim        if (Div.isUsable())
4100280031Sdim          Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get());
4101280031Sdim        if (!Div.isUsable()) {
4102280031Sdim          HasErrors = true;
4103280031Sdim          break;
4104280031Sdim        }
4105280031Sdim      }
4106280031Sdim      if (!Update.isUsable() || !Final.isUsable()) {
4107280031Sdim        HasErrors = true;
4108280031Sdim        break;
4109280031Sdim      }
4110280031Sdim      // Save results
4111280031Sdim      Built.Counters[Cnt] = IS.CounterVar;
4112296417Sdim      Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
4113288943Sdim      Built.Inits[Cnt] = Init.get();
4114280031Sdim      Built.Updates[Cnt] = Update.get();
4115280031Sdim      Built.Finals[Cnt] = Final.get();
4116280031Sdim    }
4117280031Sdim  }
4118280031Sdim
4119280031Sdim  if (HasErrors)
4120280031Sdim    return 0;
4121280031Sdim
4122280031Sdim  // Save results
4123280031Sdim  Built.IterationVarRef = IV.get();
4124280031Sdim  Built.LastIteration = LastIteration.get();
4125288943Sdim  Built.NumIterations = NumIterations.get();
4126288943Sdim  Built.CalcLastIteration =
4127288943Sdim      SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
4128280031Sdim  Built.PreCond = PreCond.get();
4129280031Sdim  Built.Cond = Cond.get();
4130280031Sdim  Built.Init = Init.get();
4131280031Sdim  Built.Inc = Inc.get();
4132280031Sdim  Built.LB = LB.get();
4133280031Sdim  Built.UB = UB.get();
4134280031Sdim  Built.IL = IL.get();
4135280031Sdim  Built.ST = ST.get();
4136280031Sdim  Built.EUB = EUB.get();
4137280031Sdim  Built.NLB = NextLB.get();
4138280031Sdim  Built.NUB = NextUB.get();
4139280031Sdim
4140276479Sdim  return NestedLoopCount;
4141276479Sdim}
4142276479Sdim
4143296417Sdimstatic Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
4144296417Sdim  auto CollapseClauses =
4145296417Sdim      OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
4146296417Sdim  if (CollapseClauses.begin() != CollapseClauses.end())
4147296417Sdim    return (*CollapseClauses.begin())->getNumForLoops();
4148276479Sdim  return nullptr;
4149276479Sdim}
4150276479Sdim
4151296417Sdimstatic Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
4152296417Sdim  auto OrderedClauses =
4153296417Sdim      OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
4154296417Sdim  if (OrderedClauses.begin() != OrderedClauses.end())
4155296417Sdim    return (*OrderedClauses.begin())->getNumForLoops();
4156296417Sdim  return nullptr;
4157296417Sdim}
4158296417Sdim
4159296417Sdimstatic bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen,
4160296417Sdim                                      const Expr *Safelen) {
4161296417Sdim  llvm::APSInt SimdlenRes, SafelenRes;
4162296417Sdim  if (Simdlen->isValueDependent() || Simdlen->isTypeDependent() ||
4163296417Sdim      Simdlen->isInstantiationDependent() ||
4164296417Sdim      Simdlen->containsUnexpandedParameterPack())
4165296417Sdim    return false;
4166296417Sdim  if (Safelen->isValueDependent() || Safelen->isTypeDependent() ||
4167296417Sdim      Safelen->isInstantiationDependent() ||
4168296417Sdim      Safelen->containsUnexpandedParameterPack())
4169296417Sdim    return false;
4170296417Sdim  Simdlen->EvaluateAsInt(SimdlenRes, S.Context);
4171296417Sdim  Safelen->EvaluateAsInt(SafelenRes, S.Context);
4172296417Sdim  // OpenMP 4.1 [2.8.1, simd Construct, Restrictions]
4173296417Sdim  // If both simdlen and safelen clauses are specified, the value of the simdlen
4174296417Sdim  // parameter must be less than or equal to the value of the safelen parameter.
4175296417Sdim  if (SimdlenRes > SafelenRes) {
4176296417Sdim    S.Diag(Simdlen->getExprLoc(), diag::err_omp_wrong_simdlen_safelen_values)
4177296417Sdim        << Simdlen->getSourceRange() << Safelen->getSourceRange();
4178296417Sdim    return true;
4179296417Sdim  }
4180296417Sdim  return false;
4181296417Sdim}
4182296417Sdim
4183276479SdimStmtResult Sema::ActOnOpenMPSimdDirective(
4184276479Sdim    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4185276479Sdim    SourceLocation EndLoc,
4186276479Sdim    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4187296417Sdim  if (!AStmt)
4188296417Sdim    return StmtError();
4189296417Sdim
4190296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4191280031Sdim  OMPLoopDirective::HelperExprs B;
4192296417Sdim  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4193296417Sdim  // define the nested loops number.
4194296417Sdim  unsigned NestedLoopCount = CheckOpenMPLoop(
4195296417Sdim      OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
4196296417Sdim      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
4197276479Sdim  if (NestedLoopCount == 0)
4198276479Sdim    return StmtError();
4199276479Sdim
4200280031Sdim  assert((CurContext->isDependentContext() || B.builtAll()) &&
4201280031Sdim         "omp simd loop exprs were not built");
4202280031Sdim
4203288943Sdim  if (!CurContext->isDependentContext()) {
4204288943Sdim    // Finalize the clauses that need pre-built expressions for CodeGen.
4205288943Sdim    for (auto C : Clauses) {
4206288943Sdim      if (auto LC = dyn_cast<OMPLinearClause>(C))
4207288943Sdim        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4208288943Sdim                                     B.NumIterations, *this, CurScope))
4209288943Sdim          return StmtError();
4210288943Sdim    }
4211288943Sdim  }
4212288943Sdim
4213296417Sdim  // OpenMP 4.1 [2.8.1, simd Construct, Restrictions]
4214296417Sdim  // If both simdlen and safelen clauses are specified, the value of the simdlen
4215296417Sdim  // parameter must be less than or equal to the value of the safelen parameter.
4216296417Sdim  OMPSafelenClause *Safelen = nullptr;
4217296417Sdim  OMPSimdlenClause *Simdlen = nullptr;
4218296417Sdim  for (auto *Clause : Clauses) {
4219296417Sdim    if (Clause->getClauseKind() == OMPC_safelen)
4220296417Sdim      Safelen = cast<OMPSafelenClause>(Clause);
4221296417Sdim    else if (Clause->getClauseKind() == OMPC_simdlen)
4222296417Sdim      Simdlen = cast<OMPSimdlenClause>(Clause);
4223296417Sdim    if (Safelen && Simdlen)
4224296417Sdim      break;
4225296417Sdim  }
4226296417Sdim  if (Simdlen && Safelen &&
4227296417Sdim      checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(),
4228296417Sdim                                Safelen->getSafelen()))
4229296417Sdim    return StmtError();
4230296417Sdim
4231276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4232276479Sdim  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
4233280031Sdim                                  Clauses, AStmt, B);
4234276479Sdim}
4235276479Sdim
4236276479SdimStmtResult Sema::ActOnOpenMPForDirective(
4237276479Sdim    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4238276479Sdim    SourceLocation EndLoc,
4239276479Sdim    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4240296417Sdim  if (!AStmt)
4241296417Sdim    return StmtError();
4242296417Sdim
4243296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4244280031Sdim  OMPLoopDirective::HelperExprs B;
4245296417Sdim  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4246296417Sdim  // define the nested loops number.
4247296417Sdim  unsigned NestedLoopCount = CheckOpenMPLoop(
4248296417Sdim      OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
4249296417Sdim      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
4250276479Sdim  if (NestedLoopCount == 0)
4251276479Sdim    return StmtError();
4252276479Sdim
4253280031Sdim  assert((CurContext->isDependentContext() || B.builtAll()) &&
4254280031Sdim         "omp for loop exprs were not built");
4255280031Sdim
4256296417Sdim  if (!CurContext->isDependentContext()) {
4257296417Sdim    // Finalize the clauses that need pre-built expressions for CodeGen.
4258296417Sdim    for (auto C : Clauses) {
4259296417Sdim      if (auto LC = dyn_cast<OMPLinearClause>(C))
4260296417Sdim        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4261296417Sdim                                     B.NumIterations, *this, CurScope))
4262296417Sdim          return StmtError();
4263296417Sdim    }
4264296417Sdim  }
4265296417Sdim
4266276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4267276479Sdim  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
4268296417Sdim                                 Clauses, AStmt, B, DSAStack->isCancelRegion());
4269276479Sdim}
4270276479Sdim
4271280031SdimStmtResult Sema::ActOnOpenMPForSimdDirective(
4272280031Sdim    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4273280031Sdim    SourceLocation EndLoc,
4274280031Sdim    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4275296417Sdim  if (!AStmt)
4276296417Sdim    return StmtError();
4277296417Sdim
4278296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4279280031Sdim  OMPLoopDirective::HelperExprs B;
4280296417Sdim  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4281296417Sdim  // define the nested loops number.
4282280031Sdim  unsigned NestedLoopCount =
4283296417Sdim      CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
4284296417Sdim                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
4285296417Sdim                      VarsWithImplicitDSA, B);
4286280031Sdim  if (NestedLoopCount == 0)
4287280031Sdim    return StmtError();
4288280031Sdim
4289280031Sdim  assert((CurContext->isDependentContext() || B.builtAll()) &&
4290280031Sdim         "omp for simd loop exprs were not built");
4291280031Sdim
4292288943Sdim  if (!CurContext->isDependentContext()) {
4293288943Sdim    // Finalize the clauses that need pre-built expressions for CodeGen.
4294288943Sdim    for (auto C : Clauses) {
4295288943Sdim      if (auto LC = dyn_cast<OMPLinearClause>(C))
4296288943Sdim        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4297288943Sdim                                     B.NumIterations, *this, CurScope))
4298288943Sdim          return StmtError();
4299288943Sdim    }
4300288943Sdim  }
4301288943Sdim
4302296417Sdim  // OpenMP 4.1 [2.8.1, simd Construct, Restrictions]
4303296417Sdim  // If both simdlen and safelen clauses are specified, the value of the simdlen
4304296417Sdim  // parameter must be less than or equal to the value of the safelen parameter.
4305296417Sdim  OMPSafelenClause *Safelen = nullptr;
4306296417Sdim  OMPSimdlenClause *Simdlen = nullptr;
4307296417Sdim  for (auto *Clause : Clauses) {
4308296417Sdim    if (Clause->getClauseKind() == OMPC_safelen)
4309296417Sdim      Safelen = cast<OMPSafelenClause>(Clause);
4310296417Sdim    else if (Clause->getClauseKind() == OMPC_simdlen)
4311296417Sdim      Simdlen = cast<OMPSimdlenClause>(Clause);
4312296417Sdim    if (Safelen && Simdlen)
4313296417Sdim      break;
4314296417Sdim  }
4315296417Sdim  if (Simdlen && Safelen &&
4316296417Sdim      checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(),
4317296417Sdim                                Safelen->getSafelen()))
4318296417Sdim    return StmtError();
4319296417Sdim
4320280031Sdim  getCurFunction()->setHasBranchProtectedScope();
4321280031Sdim  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
4322280031Sdim                                     Clauses, AStmt, B);
4323280031Sdim}
4324280031Sdim
4325276479SdimStmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
4326276479Sdim                                              Stmt *AStmt,
4327276479Sdim                                              SourceLocation StartLoc,
4328276479Sdim                                              SourceLocation EndLoc) {
4329296417Sdim  if (!AStmt)
4330296417Sdim    return StmtError();
4331296417Sdim
4332296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4333276479Sdim  auto BaseStmt = AStmt;
4334276479Sdim  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
4335276479Sdim    BaseStmt = CS->getCapturedStmt();
4336276479Sdim  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
4337276479Sdim    auto S = C->children();
4338296417Sdim    if (S.begin() == S.end())
4339276479Sdim      return StmtError();
4340276479Sdim    // All associated statements must be '#pragma omp section' except for
4341276479Sdim    // the first one.
4342296417Sdim    for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
4343276479Sdim      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
4344276479Sdim        if (SectionStmt)
4345276479Sdim          Diag(SectionStmt->getLocStart(),
4346276479Sdim               diag::err_omp_sections_substmt_not_section);
4347276479Sdim        return StmtError();
4348276479Sdim      }
4349296417Sdim      cast<OMPSectionDirective>(SectionStmt)
4350296417Sdim          ->setHasCancel(DSAStack->isCancelRegion());
4351276479Sdim    }
4352276479Sdim  } else {
4353276479Sdim    Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
4354276479Sdim    return StmtError();
4355276479Sdim  }
4356276479Sdim
4357276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4358276479Sdim
4359296417Sdim  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
4360296417Sdim                                      DSAStack->isCancelRegion());
4361276479Sdim}
4362276479Sdim
4363276479SdimStmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
4364276479Sdim                                             SourceLocation StartLoc,
4365276479Sdim                                             SourceLocation EndLoc) {
4366296417Sdim  if (!AStmt)
4367296417Sdim    return StmtError();
4368276479Sdim
4369296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4370296417Sdim
4371276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4372296417Sdim  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
4373276479Sdim
4374296417Sdim  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
4375296417Sdim                                     DSAStack->isCancelRegion());
4376276479Sdim}
4377276479Sdim
4378276479SdimStmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
4379276479Sdim                                            Stmt *AStmt,
4380276479Sdim                                            SourceLocation StartLoc,
4381276479Sdim                                            SourceLocation EndLoc) {
4382296417Sdim  if (!AStmt)
4383296417Sdim    return StmtError();
4384276479Sdim
4385296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4386296417Sdim
4387276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4388276479Sdim
4389288943Sdim  // OpenMP [2.7.3, single Construct, Restrictions]
4390288943Sdim  // The copyprivate clause must not be used with the nowait clause.
4391288943Sdim  OMPClause *Nowait = nullptr;
4392288943Sdim  OMPClause *Copyprivate = nullptr;
4393288943Sdim  for (auto *Clause : Clauses) {
4394288943Sdim    if (Clause->getClauseKind() == OMPC_nowait)
4395288943Sdim      Nowait = Clause;
4396288943Sdim    else if (Clause->getClauseKind() == OMPC_copyprivate)
4397288943Sdim      Copyprivate = Clause;
4398288943Sdim    if (Copyprivate && Nowait) {
4399288943Sdim      Diag(Copyprivate->getLocStart(),
4400288943Sdim           diag::err_omp_single_copyprivate_with_nowait);
4401288943Sdim      Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
4402288943Sdim      return StmtError();
4403288943Sdim    }
4404288943Sdim  }
4405288943Sdim
4406276479Sdim  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
4407276479Sdim}
4408276479Sdim
4409276479SdimStmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
4410276479Sdim                                            SourceLocation StartLoc,
4411276479Sdim                                            SourceLocation EndLoc) {
4412296417Sdim  if (!AStmt)
4413296417Sdim    return StmtError();
4414276479Sdim
4415296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4416296417Sdim
4417276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4418276479Sdim
4419276479Sdim  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
4420276479Sdim}
4421276479Sdim
4422296417SdimStmtResult Sema::ActOnOpenMPCriticalDirective(
4423296417Sdim    const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
4424296417Sdim    Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
4425296417Sdim  if (!AStmt)
4426296417Sdim    return StmtError();
4427276479Sdim
4428296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4429296417Sdim
4430296417Sdim  bool ErrorFound = false;
4431296417Sdim  llvm::APSInt Hint;
4432296417Sdim  SourceLocation HintLoc;
4433296417Sdim  bool DependentHint = false;
4434296417Sdim  for (auto *C : Clauses) {
4435296417Sdim    if (C->getClauseKind() == OMPC_hint) {
4436296417Sdim      if (!DirName.getName()) {
4437296417Sdim        Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
4438296417Sdim        ErrorFound = true;
4439296417Sdim      }
4440296417Sdim      Expr *E = cast<OMPHintClause>(C)->getHint();
4441296417Sdim      if (E->isTypeDependent() || E->isValueDependent() ||
4442296417Sdim          E->isInstantiationDependent())
4443296417Sdim        DependentHint = true;
4444296417Sdim      else {
4445296417Sdim        Hint = E->EvaluateKnownConstInt(Context);
4446296417Sdim        HintLoc = C->getLocStart();
4447296417Sdim      }
4448296417Sdim    }
4449296417Sdim  }
4450296417Sdim  if (ErrorFound)
4451296417Sdim    return StmtError();
4452296417Sdim  auto Pair = DSAStack->getCriticalWithHint(DirName);
4453296417Sdim  if (Pair.first && DirName.getName() && !DependentHint) {
4454296417Sdim    if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
4455296417Sdim      Diag(StartLoc, diag::err_omp_critical_with_hint);
4456296417Sdim      if (HintLoc.isValid()) {
4457296417Sdim        Diag(HintLoc, diag::note_omp_critical_hint_here)
4458296417Sdim            << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
4459296417Sdim      } else
4460296417Sdim        Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
4461296417Sdim      if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
4462296417Sdim        Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
4463296417Sdim            << 1
4464296417Sdim            << C->getHint()->EvaluateKnownConstInt(Context).toString(
4465296417Sdim                   /*Radix=*/10, /*Signed=*/false);
4466296417Sdim      } else
4467296417Sdim        Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
4468296417Sdim    }
4469296417Sdim  }
4470296417Sdim
4471276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4472276479Sdim
4473296417Sdim  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
4474296417Sdim                                           Clauses, AStmt);
4475296417Sdim  if (!Pair.first && DirName.getName() && !DependentHint)
4476296417Sdim    DSAStack->addCriticalWithHint(Dir, Hint);
4477296417Sdim  return Dir;
4478276479Sdim}
4479276479Sdim
4480276479SdimStmtResult Sema::ActOnOpenMPParallelForDirective(
4481276479Sdim    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4482276479Sdim    SourceLocation EndLoc,
4483276479Sdim    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4484296417Sdim  if (!AStmt)
4485296417Sdim    return StmtError();
4486296417Sdim
4487276479Sdim  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
4488276479Sdim  // 1.2.2 OpenMP Language Terminology
4489276479Sdim  // Structured block - An executable statement with a single entry at the
4490276479Sdim  // top and a single exit at the bottom.
4491276479Sdim  // The point of exit cannot be a branch out of the structured block.
4492276479Sdim  // longjmp() and throw() must not violate the entry/exit criteria.
4493276479Sdim  CS->getCapturedDecl()->setNothrow();
4494276479Sdim
4495280031Sdim  OMPLoopDirective::HelperExprs B;
4496296417Sdim  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4497296417Sdim  // define the nested loops number.
4498276479Sdim  unsigned NestedLoopCount =
4499296417Sdim      CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
4500296417Sdim                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
4501296417Sdim                      VarsWithImplicitDSA, B);
4502276479Sdim  if (NestedLoopCount == 0)
4503276479Sdim    return StmtError();
4504276479Sdim
4505280031Sdim  assert((CurContext->isDependentContext() || B.builtAll()) &&
4506280031Sdim         "omp parallel for loop exprs were not built");
4507280031Sdim
4508296417Sdim  if (!CurContext->isDependentContext()) {
4509296417Sdim    // Finalize the clauses that need pre-built expressions for CodeGen.
4510296417Sdim    for (auto C : Clauses) {
4511296417Sdim      if (auto LC = dyn_cast<OMPLinearClause>(C))
4512296417Sdim        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4513296417Sdim                                     B.NumIterations, *this, CurScope))
4514296417Sdim          return StmtError();
4515296417Sdim    }
4516296417Sdim  }
4517296417Sdim
4518276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4519276479Sdim  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
4520296417Sdim                                         NestedLoopCount, Clauses, AStmt, B,
4521296417Sdim                                         DSAStack->isCancelRegion());
4522276479Sdim}
4523276479Sdim
4524280031SdimStmtResult Sema::ActOnOpenMPParallelForSimdDirective(
4525280031Sdim    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4526280031Sdim    SourceLocation EndLoc,
4527280031Sdim    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4528296417Sdim  if (!AStmt)
4529296417Sdim    return StmtError();
4530296417Sdim
4531280031Sdim  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
4532280031Sdim  // 1.2.2 OpenMP Language Terminology
4533280031Sdim  // Structured block - An executable statement with a single entry at the
4534280031Sdim  // top and a single exit at the bottom.
4535280031Sdim  // The point of exit cannot be a branch out of the structured block.
4536280031Sdim  // longjmp() and throw() must not violate the entry/exit criteria.
4537280031Sdim  CS->getCapturedDecl()->setNothrow();
4538280031Sdim
4539280031Sdim  OMPLoopDirective::HelperExprs B;
4540296417Sdim  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4541296417Sdim  // define the nested loops number.
4542280031Sdim  unsigned NestedLoopCount =
4543296417Sdim      CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
4544296417Sdim                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
4545296417Sdim                      VarsWithImplicitDSA, B);
4546280031Sdim  if (NestedLoopCount == 0)
4547280031Sdim    return StmtError();
4548280031Sdim
4549288943Sdim  if (!CurContext->isDependentContext()) {
4550288943Sdim    // Finalize the clauses that need pre-built expressions for CodeGen.
4551288943Sdim    for (auto C : Clauses) {
4552288943Sdim      if (auto LC = dyn_cast<OMPLinearClause>(C))
4553288943Sdim        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4554288943Sdim                                     B.NumIterations, *this, CurScope))
4555288943Sdim          return StmtError();
4556288943Sdim    }
4557288943Sdim  }
4558288943Sdim
4559296417Sdim  // OpenMP 4.1 [2.8.1, simd Construct, Restrictions]
4560296417Sdim  // If both simdlen and safelen clauses are specified, the value of the simdlen
4561296417Sdim  // parameter must be less than or equal to the value of the safelen parameter.
4562296417Sdim  OMPSafelenClause *Safelen = nullptr;
4563296417Sdim  OMPSimdlenClause *Simdlen = nullptr;
4564296417Sdim  for (auto *Clause : Clauses) {
4565296417Sdim    if (Clause->getClauseKind() == OMPC_safelen)
4566296417Sdim      Safelen = cast<OMPSafelenClause>(Clause);
4567296417Sdim    else if (Clause->getClauseKind() == OMPC_simdlen)
4568296417Sdim      Simdlen = cast<OMPSimdlenClause>(Clause);
4569296417Sdim    if (Safelen && Simdlen)
4570296417Sdim      break;
4571296417Sdim  }
4572296417Sdim  if (Simdlen && Safelen &&
4573296417Sdim      checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(),
4574296417Sdim                                Safelen->getSafelen()))
4575296417Sdim    return StmtError();
4576296417Sdim
4577280031Sdim  getCurFunction()->setHasBranchProtectedScope();
4578280031Sdim  return OMPParallelForSimdDirective::Create(
4579280031Sdim      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
4580280031Sdim}
4581280031Sdim
4582276479SdimStmtResult
4583276479SdimSema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
4584276479Sdim                                           Stmt *AStmt, SourceLocation StartLoc,
4585276479Sdim                                           SourceLocation EndLoc) {
4586296417Sdim  if (!AStmt)
4587296417Sdim    return StmtError();
4588296417Sdim
4589296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4590276479Sdim  auto BaseStmt = AStmt;
4591276479Sdim  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
4592276479Sdim    BaseStmt = CS->getCapturedStmt();
4593276479Sdim  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
4594276479Sdim    auto S = C->children();
4595296417Sdim    if (S.begin() == S.end())
4596276479Sdim      return StmtError();
4597276479Sdim    // All associated statements must be '#pragma omp section' except for
4598276479Sdim    // the first one.
4599296417Sdim    for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
4600276479Sdim      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
4601276479Sdim        if (SectionStmt)
4602276479Sdim          Diag(SectionStmt->getLocStart(),
4603276479Sdim               diag::err_omp_parallel_sections_substmt_not_section);
4604276479Sdim        return StmtError();
4605276479Sdim      }
4606296417Sdim      cast<OMPSectionDirective>(SectionStmt)
4607296417Sdim          ->setHasCancel(DSAStack->isCancelRegion());
4608276479Sdim    }
4609276479Sdim  } else {
4610276479Sdim    Diag(AStmt->getLocStart(),
4611276479Sdim         diag::err_omp_parallel_sections_not_compound_stmt);
4612276479Sdim    return StmtError();
4613276479Sdim  }
4614276479Sdim
4615276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4616276479Sdim
4617296417Sdim  return OMPParallelSectionsDirective::Create(
4618296417Sdim      Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
4619276479Sdim}
4620276479Sdim
4621276479SdimStmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
4622276479Sdim                                          Stmt *AStmt, SourceLocation StartLoc,
4623276479Sdim                                          SourceLocation EndLoc) {
4624296417Sdim  if (!AStmt)
4625296417Sdim    return StmtError();
4626296417Sdim
4627276479Sdim  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
4628276479Sdim  // 1.2.2 OpenMP Language Terminology
4629276479Sdim  // Structured block - An executable statement with a single entry at the
4630276479Sdim  // top and a single exit at the bottom.
4631276479Sdim  // The point of exit cannot be a branch out of the structured block.
4632276479Sdim  // longjmp() and throw() must not violate the entry/exit criteria.
4633276479Sdim  CS->getCapturedDecl()->setNothrow();
4634276479Sdim
4635276479Sdim  getCurFunction()->setHasBranchProtectedScope();
4636276479Sdim
4637296417Sdim  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
4638296417Sdim                                  DSAStack->isCancelRegion());
4639276479Sdim}
4640276479Sdim
4641276479SdimStmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
4642276479Sdim                                               SourceLocation EndLoc) {
4643276479Sdim  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
4644276479Sdim}
4645276479Sdim
4646276479SdimStmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
4647276479Sdim                                             SourceLocation EndLoc) {
4648276479Sdim  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
4649276479Sdim}
4650276479Sdim
4651276479SdimStmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
4652276479Sdim                                              SourceLocation EndLoc) {
4653276479Sdim  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
4654276479Sdim}
4655276479Sdim
4656288943SdimStmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt,
4657288943Sdim                                               SourceLocation StartLoc,
4658288943Sdim                                               SourceLocation EndLoc) {
4659296417Sdim  if (!AStmt)
4660296417Sdim    return StmtError();
4661288943Sdim
4662296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4663296417Sdim
4664288943Sdim  getCurFunction()->setHasBranchProtectedScope();
4665288943Sdim
4666288943Sdim  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt);
4667288943Sdim}
4668288943Sdim
4669276479SdimStmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
4670276479Sdim                                           SourceLocation StartLoc,
4671276479Sdim                                           SourceLocation EndLoc) {
4672276479Sdim  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
4673276479Sdim  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
4674276479Sdim}
4675276479Sdim
4676296417SdimStmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
4677296417Sdim                                             Stmt *AStmt,
4678280031Sdim                                             SourceLocation StartLoc,
4679280031Sdim                                             SourceLocation EndLoc) {
4680296417Sdim  OMPClause *DependFound = nullptr;
4681296417Sdim  OMPClause *DependSourceClause = nullptr;
4682296417Sdim  OMPClause *DependSinkClause = nullptr;
4683296417Sdim  bool ErrorFound = false;
4684296417Sdim  OMPThreadsClause *TC = nullptr;
4685296417Sdim  OMPSIMDClause *SC = nullptr;
4686296417Sdim  for (auto *C : Clauses) {
4687296417Sdim    if (auto *DC = dyn_cast<OMPDependClause>(C)) {
4688296417Sdim      DependFound = C;
4689296417Sdim      if (DC->getDependencyKind() == OMPC_DEPEND_source) {
4690296417Sdim        if (DependSourceClause) {
4691296417Sdim          Diag(C->getLocStart(), diag::err_omp_more_one_clause)
4692296417Sdim              << getOpenMPDirectiveName(OMPD_ordered)
4693296417Sdim              << getOpenMPClauseName(OMPC_depend) << 2;
4694296417Sdim          ErrorFound = true;
4695296417Sdim        } else
4696296417Sdim          DependSourceClause = C;
4697296417Sdim        if (DependSinkClause) {
4698296417Sdim          Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
4699296417Sdim              << 0;
4700296417Sdim          ErrorFound = true;
4701296417Sdim        }
4702296417Sdim      } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
4703296417Sdim        if (DependSourceClause) {
4704296417Sdim          Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
4705296417Sdim              << 1;
4706296417Sdim          ErrorFound = true;
4707296417Sdim        }
4708296417Sdim        DependSinkClause = C;
4709296417Sdim      }
4710296417Sdim    } else if (C->getClauseKind() == OMPC_threads)
4711296417Sdim      TC = cast<OMPThreadsClause>(C);
4712296417Sdim    else if (C->getClauseKind() == OMPC_simd)
4713296417Sdim      SC = cast<OMPSIMDClause>(C);
4714296417Sdim  }
4715296417Sdim  if (!ErrorFound && !SC &&
4716296417Sdim      isOpenMPSimdDirective(DSAStack->getParentDirective())) {
4717296417Sdim    // OpenMP [2.8.1,simd Construct, Restrictions]
4718296417Sdim    // An ordered construct with the simd clause is the only OpenMP construct
4719296417Sdim    // that can appear in the simd region.
4720296417Sdim    Diag(StartLoc, diag::err_omp_prohibited_region_simd);
4721296417Sdim    ErrorFound = true;
4722296417Sdim  } else if (DependFound && (TC || SC)) {
4723296417Sdim    Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
4724296417Sdim        << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
4725296417Sdim    ErrorFound = true;
4726296417Sdim  } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) {
4727296417Sdim    Diag(DependFound->getLocStart(),
4728296417Sdim         diag::err_omp_ordered_directive_without_param);
4729296417Sdim    ErrorFound = true;
4730296417Sdim  } else if (TC || Clauses.empty()) {
4731296417Sdim    if (auto *Param = DSAStack->getParentOrderedRegionParam()) {
4732296417Sdim      SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
4733296417Sdim      Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
4734296417Sdim          << (TC != nullptr);
4735296417Sdim      Diag(Param->getLocStart(), diag::note_omp_ordered_param);
4736296417Sdim      ErrorFound = true;
4737296417Sdim    }
4738296417Sdim  }
4739296417Sdim  if ((!AStmt && !DependFound) || ErrorFound)
4740296417Sdim    return StmtError();
4741280031Sdim
4742296417Sdim  if (AStmt) {
4743296417Sdim    assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4744280031Sdim
4745296417Sdim    getCurFunction()->setHasBranchProtectedScope();
4746296417Sdim  }
4747296417Sdim
4748296417Sdim  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
4749280031Sdim}
4750280031Sdim
4751288943Sdimnamespace {
4752288943Sdim/// \brief Helper class for checking expression in 'omp atomic [update]'
4753288943Sdim/// construct.
4754288943Sdimclass OpenMPAtomicUpdateChecker {
4755288943Sdim  /// \brief Error results for atomic update expressions.
4756288943Sdim  enum ExprAnalysisErrorCode {
4757288943Sdim    /// \brief A statement is not an expression statement.
4758288943Sdim    NotAnExpression,
4759288943Sdim    /// \brief Expression is not builtin binary or unary operation.
4760288943Sdim    NotABinaryOrUnaryExpression,
4761288943Sdim    /// \brief Unary operation is not post-/pre- increment/decrement operation.
4762288943Sdim    NotAnUnaryIncDecExpression,
4763288943Sdim    /// \brief An expression is not of scalar type.
4764288943Sdim    NotAScalarType,
4765288943Sdim    /// \brief A binary operation is not an assignment operation.
4766288943Sdim    NotAnAssignmentOp,
4767288943Sdim    /// \brief RHS part of the binary operation is not a binary expression.
4768288943Sdim    NotABinaryExpression,
4769288943Sdim    /// \brief RHS part is not additive/multiplicative/shift/biwise binary
4770288943Sdim    /// expression.
4771288943Sdim    NotABinaryOperator,
4772288943Sdim    /// \brief RHS binary operation does not have reference to the updated LHS
4773288943Sdim    /// part.
4774288943Sdim    NotAnUpdateExpression,
4775288943Sdim    /// \brief No errors is found.
4776288943Sdim    NoError
4777288943Sdim  };
4778288943Sdim  /// \brief Reference to Sema.
4779288943Sdim  Sema &SemaRef;
4780288943Sdim  /// \brief A location for note diagnostics (when error is found).
4781288943Sdim  SourceLocation NoteLoc;
4782288943Sdim  /// \brief 'x' lvalue part of the source atomic expression.
4783288943Sdim  Expr *X;
4784288943Sdim  /// \brief 'expr' rvalue part of the source atomic expression.
4785288943Sdim  Expr *E;
4786288943Sdim  /// \brief Helper expression of the form
4787288943Sdim  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
4788288943Sdim  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
4789288943Sdim  Expr *UpdateExpr;
4790288943Sdim  /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
4791288943Sdim  /// important for non-associative operations.
4792288943Sdim  bool IsXLHSInRHSPart;
4793288943Sdim  BinaryOperatorKind Op;
4794288943Sdim  SourceLocation OpLoc;
4795288943Sdim  /// \brief true if the source expression is a postfix unary operation, false
4796288943Sdim  /// if it is a prefix unary operation.
4797288943Sdim  bool IsPostfixUpdate;
4798288943Sdim
4799288943Sdimpublic:
4800288943Sdim  OpenMPAtomicUpdateChecker(Sema &SemaRef)
4801288943Sdim      : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
4802288943Sdim        IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
4803288943Sdim  /// \brief Check specified statement that it is suitable for 'atomic update'
4804288943Sdim  /// constructs and extract 'x', 'expr' and Operation from the original
4805288943Sdim  /// expression. If DiagId and NoteId == 0, then only check is performed
4806288943Sdim  /// without error notification.
4807288943Sdim  /// \param DiagId Diagnostic which should be emitted if error is found.
4808288943Sdim  /// \param NoteId Diagnostic note for the main error message.
4809288943Sdim  /// \return true if statement is not an update expression, false otherwise.
4810288943Sdim  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
4811288943Sdim  /// \brief Return the 'x' lvalue part of the source atomic expression.
4812288943Sdim  Expr *getX() const { return X; }
4813288943Sdim  /// \brief Return the 'expr' rvalue part of the source atomic expression.
4814288943Sdim  Expr *getExpr() const { return E; }
4815288943Sdim  /// \brief Return the update expression used in calculation of the updated
4816288943Sdim  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
4817288943Sdim  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
4818288943Sdim  Expr *getUpdateExpr() const { return UpdateExpr; }
4819288943Sdim  /// \brief Return true if 'x' is LHS in RHS part of full update expression,
4820288943Sdim  /// false otherwise.
4821288943Sdim  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
4822288943Sdim
4823288943Sdim  /// \brief true if the source expression is a postfix unary operation, false
4824288943Sdim  /// if it is a prefix unary operation.
4825288943Sdim  bool isPostfixUpdate() const { return IsPostfixUpdate; }
4826288943Sdim
4827288943Sdimprivate:
4828288943Sdim  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
4829288943Sdim                            unsigned NoteId = 0);
4830288943Sdim};
4831288943Sdim} // namespace
4832288943Sdim
4833288943Sdimbool OpenMPAtomicUpdateChecker::checkBinaryOperation(
4834288943Sdim    BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
4835288943Sdim  ExprAnalysisErrorCode ErrorFound = NoError;
4836288943Sdim  SourceLocation ErrorLoc, NoteLoc;
4837288943Sdim  SourceRange ErrorRange, NoteRange;
4838288943Sdim  // Allowed constructs are:
4839288943Sdim  //  x = x binop expr;
4840288943Sdim  //  x = expr binop x;
4841288943Sdim  if (AtomicBinOp->getOpcode() == BO_Assign) {
4842288943Sdim    X = AtomicBinOp->getLHS();
4843288943Sdim    if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
4844288943Sdim            AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
4845288943Sdim      if (AtomicInnerBinOp->isMultiplicativeOp() ||
4846288943Sdim          AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
4847288943Sdim          AtomicInnerBinOp->isBitwiseOp()) {
4848288943Sdim        Op = AtomicInnerBinOp->getOpcode();
4849288943Sdim        OpLoc = AtomicInnerBinOp->getOperatorLoc();
4850288943Sdim        auto *LHS = AtomicInnerBinOp->getLHS();
4851288943Sdim        auto *RHS = AtomicInnerBinOp->getRHS();
4852288943Sdim        llvm::FoldingSetNodeID XId, LHSId, RHSId;
4853288943Sdim        X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
4854288943Sdim                                          /*Canonical=*/true);
4855288943Sdim        LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
4856288943Sdim                                            /*Canonical=*/true);
4857288943Sdim        RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
4858288943Sdim                                            /*Canonical=*/true);
4859288943Sdim        if (XId == LHSId) {
4860288943Sdim          E = RHS;
4861288943Sdim          IsXLHSInRHSPart = true;
4862288943Sdim        } else if (XId == RHSId) {
4863288943Sdim          E = LHS;
4864288943Sdim          IsXLHSInRHSPart = false;
4865288943Sdim        } else {
4866288943Sdim          ErrorLoc = AtomicInnerBinOp->getExprLoc();
4867288943Sdim          ErrorRange = AtomicInnerBinOp->getSourceRange();
4868288943Sdim          NoteLoc = X->getExprLoc();
4869288943Sdim          NoteRange = X->getSourceRange();
4870288943Sdim          ErrorFound = NotAnUpdateExpression;
4871288943Sdim        }
4872288943Sdim      } else {
4873288943Sdim        ErrorLoc = AtomicInnerBinOp->getExprLoc();
4874288943Sdim        ErrorRange = AtomicInnerBinOp->getSourceRange();
4875288943Sdim        NoteLoc = AtomicInnerBinOp->getOperatorLoc();
4876288943Sdim        NoteRange = SourceRange(NoteLoc, NoteLoc);
4877288943Sdim        ErrorFound = NotABinaryOperator;
4878288943Sdim      }
4879288943Sdim    } else {
4880288943Sdim      NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
4881288943Sdim      NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
4882288943Sdim      ErrorFound = NotABinaryExpression;
4883288943Sdim    }
4884288943Sdim  } else {
4885288943Sdim    ErrorLoc = AtomicBinOp->getExprLoc();
4886288943Sdim    ErrorRange = AtomicBinOp->getSourceRange();
4887288943Sdim    NoteLoc = AtomicBinOp->getOperatorLoc();
4888288943Sdim    NoteRange = SourceRange(NoteLoc, NoteLoc);
4889288943Sdim    ErrorFound = NotAnAssignmentOp;
4890288943Sdim  }
4891288943Sdim  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
4892288943Sdim    SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
4893288943Sdim    SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
4894288943Sdim    return true;
4895288943Sdim  } else if (SemaRef.CurContext->isDependentContext())
4896288943Sdim    E = X = UpdateExpr = nullptr;
4897288943Sdim  return ErrorFound != NoError;
4898288943Sdim}
4899288943Sdim
4900288943Sdimbool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
4901288943Sdim                                               unsigned NoteId) {
4902288943Sdim  ExprAnalysisErrorCode ErrorFound = NoError;
4903288943Sdim  SourceLocation ErrorLoc, NoteLoc;
4904288943Sdim  SourceRange ErrorRange, NoteRange;
4905288943Sdim  // Allowed constructs are:
4906288943Sdim  //  x++;
4907288943Sdim  //  x--;
4908288943Sdim  //  ++x;
4909288943Sdim  //  --x;
4910288943Sdim  //  x binop= expr;
4911288943Sdim  //  x = x binop expr;
4912288943Sdim  //  x = expr binop x;
4913288943Sdim  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
4914288943Sdim    AtomicBody = AtomicBody->IgnoreParenImpCasts();
4915288943Sdim    if (AtomicBody->getType()->isScalarType() ||
4916288943Sdim        AtomicBody->isInstantiationDependent()) {
4917288943Sdim      if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
4918288943Sdim              AtomicBody->IgnoreParenImpCasts())) {
4919288943Sdim        // Check for Compound Assignment Operation
4920288943Sdim        Op = BinaryOperator::getOpForCompoundAssignment(
4921288943Sdim            AtomicCompAssignOp->getOpcode());
4922288943Sdim        OpLoc = AtomicCompAssignOp->getOperatorLoc();
4923288943Sdim        E = AtomicCompAssignOp->getRHS();
4924288943Sdim        X = AtomicCompAssignOp->getLHS();
4925288943Sdim        IsXLHSInRHSPart = true;
4926288943Sdim      } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
4927288943Sdim                     AtomicBody->IgnoreParenImpCasts())) {
4928288943Sdim        // Check for Binary Operation
4929288943Sdim        if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
4930288943Sdim          return true;
4931288943Sdim      } else if (auto *AtomicUnaryOp =
4932288943Sdim                 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) {
4933288943Sdim        // Check for Unary Operation
4934288943Sdim        if (AtomicUnaryOp->isIncrementDecrementOp()) {
4935288943Sdim          IsPostfixUpdate = AtomicUnaryOp->isPostfix();
4936288943Sdim          Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
4937288943Sdim          OpLoc = AtomicUnaryOp->getOperatorLoc();
4938288943Sdim          X = AtomicUnaryOp->getSubExpr();
4939288943Sdim          E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
4940288943Sdim          IsXLHSInRHSPart = true;
4941288943Sdim        } else {
4942288943Sdim          ErrorFound = NotAnUnaryIncDecExpression;
4943288943Sdim          ErrorLoc = AtomicUnaryOp->getExprLoc();
4944288943Sdim          ErrorRange = AtomicUnaryOp->getSourceRange();
4945288943Sdim          NoteLoc = AtomicUnaryOp->getOperatorLoc();
4946288943Sdim          NoteRange = SourceRange(NoteLoc, NoteLoc);
4947288943Sdim        }
4948296417Sdim      } else if (!AtomicBody->isInstantiationDependent()) {
4949288943Sdim        ErrorFound = NotABinaryOrUnaryExpression;
4950288943Sdim        NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
4951288943Sdim        NoteRange = ErrorRange = AtomicBody->getSourceRange();
4952288943Sdim      }
4953288943Sdim    } else {
4954288943Sdim      ErrorFound = NotAScalarType;
4955288943Sdim      NoteLoc = ErrorLoc = AtomicBody->getLocStart();
4956288943Sdim      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
4957288943Sdim    }
4958288943Sdim  } else {
4959288943Sdim    ErrorFound = NotAnExpression;
4960288943Sdim    NoteLoc = ErrorLoc = S->getLocStart();
4961288943Sdim    NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
4962288943Sdim  }
4963288943Sdim  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
4964288943Sdim    SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
4965288943Sdim    SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
4966288943Sdim    return true;
4967288943Sdim  } else if (SemaRef.CurContext->isDependentContext())
4968288943Sdim    E = X = UpdateExpr = nullptr;
4969288943Sdim  if (ErrorFound == NoError && E && X) {
4970288943Sdim    // Build an update expression of form 'OpaqueValueExpr(x) binop
4971288943Sdim    // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
4972288943Sdim    // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
4973288943Sdim    auto *OVEX = new (SemaRef.getASTContext())
4974288943Sdim        OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
4975288943Sdim    auto *OVEExpr = new (SemaRef.getASTContext())
4976288943Sdim        OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
4977288943Sdim    auto Update =
4978288943Sdim        SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
4979288943Sdim                                   IsXLHSInRHSPart ? OVEExpr : OVEX);
4980288943Sdim    if (Update.isInvalid())
4981288943Sdim      return true;
4982288943Sdim    Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
4983288943Sdim                                               Sema::AA_Casting);
4984288943Sdim    if (Update.isInvalid())
4985288943Sdim      return true;
4986288943Sdim    UpdateExpr = Update.get();
4987288943Sdim  }
4988288943Sdim  return ErrorFound != NoError;
4989288943Sdim}
4990288943Sdim
4991280031SdimStmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
4992280031Sdim                                            Stmt *AStmt,
4993280031Sdim                                            SourceLocation StartLoc,
4994280031Sdim                                            SourceLocation EndLoc) {
4995296417Sdim  if (!AStmt)
4996296417Sdim    return StmtError();
4997296417Sdim
4998280031Sdim  auto CS = cast<CapturedStmt>(AStmt);
4999280031Sdim  // 1.2.2 OpenMP Language Terminology
5000280031Sdim  // Structured block - An executable statement with a single entry at the
5001280031Sdim  // top and a single exit at the bottom.
5002280031Sdim  // The point of exit cannot be a branch out of the structured block.
5003280031Sdim  // longjmp() and throw() must not violate the entry/exit criteria.
5004280031Sdim  OpenMPClauseKind AtomicKind = OMPC_unknown;
5005280031Sdim  SourceLocation AtomicKindLoc;
5006280031Sdim  for (auto *C : Clauses) {
5007280031Sdim    if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
5008280031Sdim        C->getClauseKind() == OMPC_update ||
5009280031Sdim        C->getClauseKind() == OMPC_capture) {
5010280031Sdim      if (AtomicKind != OMPC_unknown) {
5011280031Sdim        Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
5012280031Sdim            << SourceRange(C->getLocStart(), C->getLocEnd());
5013280031Sdim        Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
5014280031Sdim            << getOpenMPClauseName(AtomicKind);
5015280031Sdim      } else {
5016280031Sdim        AtomicKind = C->getClauseKind();
5017280031Sdim        AtomicKindLoc = C->getLocStart();
5018280031Sdim      }
5019280031Sdim    }
5020280031Sdim  }
5021280031Sdim
5022280031Sdim  auto Body = CS->getCapturedStmt();
5023288943Sdim  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
5024288943Sdim    Body = EWC->getSubExpr();
5025288943Sdim
5026280031Sdim  Expr *X = nullptr;
5027280031Sdim  Expr *V = nullptr;
5028280031Sdim  Expr *E = nullptr;
5029288943Sdim  Expr *UE = nullptr;
5030288943Sdim  bool IsXLHSInRHSPart = false;
5031288943Sdim  bool IsPostfixUpdate = false;
5032280031Sdim  // OpenMP [2.12.6, atomic Construct]
5033280031Sdim  // In the next expressions:
5034280031Sdim  // * x and v (as applicable) are both l-value expressions with scalar type.
5035280031Sdim  // * During the execution of an atomic region, multiple syntactic
5036280031Sdim  // occurrences of x must designate the same storage location.
5037280031Sdim  // * Neither of v and expr (as applicable) may access the storage location
5038280031Sdim  // designated by x.
5039280031Sdim  // * Neither of x and expr (as applicable) may access the storage location
5040280031Sdim  // designated by v.
5041280031Sdim  // * expr is an expression with scalar type.
5042280031Sdim  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
5043280031Sdim  // * binop, binop=, ++, and -- are not overloaded operators.
5044280031Sdim  // * The expression x binop expr must be numerically equivalent to x binop
5045280031Sdim  // (expr). This requirement is satisfied if the operators in expr have
5046280031Sdim  // precedence greater than binop, or by using parentheses around expr or
5047280031Sdim  // subexpressions of expr.
5048280031Sdim  // * The expression expr binop x must be numerically equivalent to (expr)
5049280031Sdim  // binop x. This requirement is satisfied if the operators in expr have
5050280031Sdim  // precedence equal to or greater than binop, or by using parentheses around
5051280031Sdim  // expr or subexpressions of expr.
5052280031Sdim  // * For forms that allow multiple occurrences of x, the number of times
5053280031Sdim  // that x is evaluated is unspecified.
5054280031Sdim  if (AtomicKind == OMPC_read) {
5055288943Sdim    enum {
5056288943Sdim      NotAnExpression,
5057288943Sdim      NotAnAssignmentOp,
5058288943Sdim      NotAScalarType,
5059288943Sdim      NotAnLValue,
5060288943Sdim      NoError
5061288943Sdim    } ErrorFound = NoError;
5062280031Sdim    SourceLocation ErrorLoc, NoteLoc;
5063280031Sdim    SourceRange ErrorRange, NoteRange;
5064280031Sdim    // If clause is read:
5065280031Sdim    //  v = x;
5066280031Sdim    if (auto AtomicBody = dyn_cast<Expr>(Body)) {
5067280031Sdim      auto AtomicBinOp =
5068280031Sdim          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5069280031Sdim      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5070280031Sdim        X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
5071280031Sdim        V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
5072280031Sdim        if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
5073280031Sdim            (V->isInstantiationDependent() || V->getType()->isScalarType())) {
5074280031Sdim          if (!X->isLValue() || !V->isLValue()) {
5075280031Sdim            auto NotLValueExpr = X->isLValue() ? V : X;
5076280031Sdim            ErrorFound = NotAnLValue;
5077280031Sdim            ErrorLoc = AtomicBinOp->getExprLoc();
5078280031Sdim            ErrorRange = AtomicBinOp->getSourceRange();
5079280031Sdim            NoteLoc = NotLValueExpr->getExprLoc();
5080280031Sdim            NoteRange = NotLValueExpr->getSourceRange();
5081280031Sdim          }
5082280031Sdim        } else if (!X->isInstantiationDependent() ||
5083280031Sdim                   !V->isInstantiationDependent()) {
5084280031Sdim          auto NotScalarExpr =
5085280031Sdim              (X->isInstantiationDependent() || X->getType()->isScalarType())
5086280031Sdim                  ? V
5087280031Sdim                  : X;
5088280031Sdim          ErrorFound = NotAScalarType;
5089280031Sdim          ErrorLoc = AtomicBinOp->getExprLoc();
5090280031Sdim          ErrorRange = AtomicBinOp->getSourceRange();
5091280031Sdim          NoteLoc = NotScalarExpr->getExprLoc();
5092280031Sdim          NoteRange = NotScalarExpr->getSourceRange();
5093280031Sdim        }
5094296417Sdim      } else if (!AtomicBody->isInstantiationDependent()) {
5095280031Sdim        ErrorFound = NotAnAssignmentOp;
5096280031Sdim        ErrorLoc = AtomicBody->getExprLoc();
5097280031Sdim        ErrorRange = AtomicBody->getSourceRange();
5098280031Sdim        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5099280031Sdim                              : AtomicBody->getExprLoc();
5100280031Sdim        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5101280031Sdim                                : AtomicBody->getSourceRange();
5102280031Sdim      }
5103280031Sdim    } else {
5104280031Sdim      ErrorFound = NotAnExpression;
5105280031Sdim      NoteLoc = ErrorLoc = Body->getLocStart();
5106280031Sdim      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5107280031Sdim    }
5108280031Sdim    if (ErrorFound != NoError) {
5109280031Sdim      Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
5110280031Sdim          << ErrorRange;
5111280031Sdim      Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5112280031Sdim                                                      << NoteRange;
5113280031Sdim      return StmtError();
5114280031Sdim    } else if (CurContext->isDependentContext())
5115280031Sdim      V = X = nullptr;
5116280031Sdim  } else if (AtomicKind == OMPC_write) {
5117288943Sdim    enum {
5118288943Sdim      NotAnExpression,
5119288943Sdim      NotAnAssignmentOp,
5120288943Sdim      NotAScalarType,
5121288943Sdim      NotAnLValue,
5122288943Sdim      NoError
5123288943Sdim    } ErrorFound = NoError;
5124280031Sdim    SourceLocation ErrorLoc, NoteLoc;
5125280031Sdim    SourceRange ErrorRange, NoteRange;
5126280031Sdim    // If clause is write:
5127280031Sdim    //  x = expr;
5128280031Sdim    if (auto AtomicBody = dyn_cast<Expr>(Body)) {
5129280031Sdim      auto AtomicBinOp =
5130280031Sdim          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5131280031Sdim      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5132288943Sdim        X = AtomicBinOp->getLHS();
5133288943Sdim        E = AtomicBinOp->getRHS();
5134280031Sdim        if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
5135280031Sdim            (E->isInstantiationDependent() || E->getType()->isScalarType())) {
5136280031Sdim          if (!X->isLValue()) {
5137280031Sdim            ErrorFound = NotAnLValue;
5138280031Sdim            ErrorLoc = AtomicBinOp->getExprLoc();
5139280031Sdim            ErrorRange = AtomicBinOp->getSourceRange();
5140280031Sdim            NoteLoc = X->getExprLoc();
5141280031Sdim            NoteRange = X->getSourceRange();
5142280031Sdim          }
5143280031Sdim        } else if (!X->isInstantiationDependent() ||
5144280031Sdim                   !E->isInstantiationDependent()) {
5145280031Sdim          auto NotScalarExpr =
5146280031Sdim              (X->isInstantiationDependent() || X->getType()->isScalarType())
5147280031Sdim                  ? E
5148280031Sdim                  : X;
5149280031Sdim          ErrorFound = NotAScalarType;
5150280031Sdim          ErrorLoc = AtomicBinOp->getExprLoc();
5151280031Sdim          ErrorRange = AtomicBinOp->getSourceRange();
5152280031Sdim          NoteLoc = NotScalarExpr->getExprLoc();
5153280031Sdim          NoteRange = NotScalarExpr->getSourceRange();
5154280031Sdim        }
5155296417Sdim      } else if (!AtomicBody->isInstantiationDependent()) {
5156280031Sdim        ErrorFound = NotAnAssignmentOp;
5157280031Sdim        ErrorLoc = AtomicBody->getExprLoc();
5158280031Sdim        ErrorRange = AtomicBody->getSourceRange();
5159280031Sdim        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5160280031Sdim                              : AtomicBody->getExprLoc();
5161280031Sdim        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5162280031Sdim                                : AtomicBody->getSourceRange();
5163280031Sdim      }
5164280031Sdim    } else {
5165280031Sdim      ErrorFound = NotAnExpression;
5166280031Sdim      NoteLoc = ErrorLoc = Body->getLocStart();
5167280031Sdim      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5168280031Sdim    }
5169280031Sdim    if (ErrorFound != NoError) {
5170280031Sdim      Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
5171280031Sdim          << ErrorRange;
5172280031Sdim      Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5173280031Sdim                                                      << NoteRange;
5174280031Sdim      return StmtError();
5175280031Sdim    } else if (CurContext->isDependentContext())
5176280031Sdim      E = X = nullptr;
5177280031Sdim  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
5178288943Sdim    // If clause is update:
5179288943Sdim    //  x++;
5180288943Sdim    //  x--;
5181288943Sdim    //  ++x;
5182288943Sdim    //  --x;
5183288943Sdim    //  x binop= expr;
5184288943Sdim    //  x = x binop expr;
5185288943Sdim    //  x = expr binop x;
5186288943Sdim    OpenMPAtomicUpdateChecker Checker(*this);
5187288943Sdim    if (Checker.checkStatement(
5188288943Sdim            Body, (AtomicKind == OMPC_update)
5189288943Sdim                      ? diag::err_omp_atomic_update_not_expression_statement
5190288943Sdim                      : diag::err_omp_atomic_not_expression_statement,
5191288943Sdim            diag::note_omp_atomic_update))
5192280031Sdim      return StmtError();
5193288943Sdim    if (!CurContext->isDependentContext()) {
5194288943Sdim      E = Checker.getExpr();
5195288943Sdim      X = Checker.getX();
5196288943Sdim      UE = Checker.getUpdateExpr();
5197288943Sdim      IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5198280031Sdim    }
5199280031Sdim  } else if (AtomicKind == OMPC_capture) {
5200288943Sdim    enum {
5201288943Sdim      NotAnAssignmentOp,
5202288943Sdim      NotACompoundStatement,
5203288943Sdim      NotTwoSubstatements,
5204288943Sdim      NotASpecificExpression,
5205288943Sdim      NoError
5206288943Sdim    } ErrorFound = NoError;
5207288943Sdim    SourceLocation ErrorLoc, NoteLoc;
5208288943Sdim    SourceRange ErrorRange, NoteRange;
5209288943Sdim    if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
5210288943Sdim      // If clause is a capture:
5211288943Sdim      //  v = x++;
5212288943Sdim      //  v = x--;
5213288943Sdim      //  v = ++x;
5214288943Sdim      //  v = --x;
5215288943Sdim      //  v = x binop= expr;
5216288943Sdim      //  v = x = x binop expr;
5217288943Sdim      //  v = x = expr binop x;
5218288943Sdim      auto *AtomicBinOp =
5219288943Sdim          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5220288943Sdim      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5221288943Sdim        V = AtomicBinOp->getLHS();
5222288943Sdim        Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
5223288943Sdim        OpenMPAtomicUpdateChecker Checker(*this);
5224288943Sdim        if (Checker.checkStatement(
5225288943Sdim                Body, diag::err_omp_atomic_capture_not_expression_statement,
5226288943Sdim                diag::note_omp_atomic_update))
5227288943Sdim          return StmtError();
5228288943Sdim        E = Checker.getExpr();
5229288943Sdim        X = Checker.getX();
5230288943Sdim        UE = Checker.getUpdateExpr();
5231288943Sdim        IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5232288943Sdim        IsPostfixUpdate = Checker.isPostfixUpdate();
5233296417Sdim      } else if (!AtomicBody->isInstantiationDependent()) {
5234288943Sdim        ErrorLoc = AtomicBody->getExprLoc();
5235288943Sdim        ErrorRange = AtomicBody->getSourceRange();
5236288943Sdim        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5237288943Sdim                              : AtomicBody->getExprLoc();
5238288943Sdim        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5239288943Sdim                                : AtomicBody->getSourceRange();
5240288943Sdim        ErrorFound = NotAnAssignmentOp;
5241288943Sdim      }
5242288943Sdim      if (ErrorFound != NoError) {
5243288943Sdim        Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
5244288943Sdim            << ErrorRange;
5245288943Sdim        Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
5246288943Sdim        return StmtError();
5247288943Sdim      } else if (CurContext->isDependentContext()) {
5248288943Sdim        UE = V = E = X = nullptr;
5249288943Sdim      }
5250288943Sdim    } else {
5251288943Sdim      // If clause is a capture:
5252288943Sdim      //  { v = x; x = expr; }
5253288943Sdim      //  { v = x; x++; }
5254288943Sdim      //  { v = x; x--; }
5255288943Sdim      //  { v = x; ++x; }
5256288943Sdim      //  { v = x; --x; }
5257288943Sdim      //  { v = x; x binop= expr; }
5258288943Sdim      //  { v = x; x = x binop expr; }
5259288943Sdim      //  { v = x; x = expr binop x; }
5260288943Sdim      //  { x++; v = x; }
5261288943Sdim      //  { x--; v = x; }
5262288943Sdim      //  { ++x; v = x; }
5263288943Sdim      //  { --x; v = x; }
5264288943Sdim      //  { x binop= expr; v = x; }
5265288943Sdim      //  { x = x binop expr; v = x; }
5266288943Sdim      //  { x = expr binop x; v = x; }
5267288943Sdim      if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
5268288943Sdim        // Check that this is { expr1; expr2; }
5269288943Sdim        if (CS->size() == 2) {
5270288943Sdim          auto *First = CS->body_front();
5271288943Sdim          auto *Second = CS->body_back();
5272288943Sdim          if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
5273288943Sdim            First = EWC->getSubExpr()->IgnoreParenImpCasts();
5274288943Sdim          if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
5275288943Sdim            Second = EWC->getSubExpr()->IgnoreParenImpCasts();
5276288943Sdim          // Need to find what subexpression is 'v' and what is 'x'.
5277288943Sdim          OpenMPAtomicUpdateChecker Checker(*this);
5278288943Sdim          bool IsUpdateExprFound = !Checker.checkStatement(Second);
5279288943Sdim          BinaryOperator *BinOp = nullptr;
5280288943Sdim          if (IsUpdateExprFound) {
5281288943Sdim            BinOp = dyn_cast<BinaryOperator>(First);
5282288943Sdim            IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
5283288943Sdim          }
5284288943Sdim          if (IsUpdateExprFound && !CurContext->isDependentContext()) {
5285288943Sdim            //  { v = x; x++; }
5286288943Sdim            //  { v = x; x--; }
5287288943Sdim            //  { v = x; ++x; }
5288288943Sdim            //  { v = x; --x; }
5289288943Sdim            //  { v = x; x binop= expr; }
5290288943Sdim            //  { v = x; x = x binop expr; }
5291288943Sdim            //  { v = x; x = expr binop x; }
5292288943Sdim            // Check that the first expression has form v = x.
5293288943Sdim            auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
5294288943Sdim            llvm::FoldingSetNodeID XId, PossibleXId;
5295288943Sdim            Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
5296288943Sdim            PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
5297288943Sdim            IsUpdateExprFound = XId == PossibleXId;
5298288943Sdim            if (IsUpdateExprFound) {
5299288943Sdim              V = BinOp->getLHS();
5300288943Sdim              X = Checker.getX();
5301288943Sdim              E = Checker.getExpr();
5302288943Sdim              UE = Checker.getUpdateExpr();
5303288943Sdim              IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5304288943Sdim              IsPostfixUpdate = true;
5305288943Sdim            }
5306288943Sdim          }
5307288943Sdim          if (!IsUpdateExprFound) {
5308288943Sdim            IsUpdateExprFound = !Checker.checkStatement(First);
5309288943Sdim            BinOp = nullptr;
5310288943Sdim            if (IsUpdateExprFound) {
5311288943Sdim              BinOp = dyn_cast<BinaryOperator>(Second);
5312288943Sdim              IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
5313288943Sdim            }
5314288943Sdim            if (IsUpdateExprFound && !CurContext->isDependentContext()) {
5315288943Sdim              //  { x++; v = x; }
5316288943Sdim              //  { x--; v = x; }
5317288943Sdim              //  { ++x; v = x; }
5318288943Sdim              //  { --x; v = x; }
5319288943Sdim              //  { x binop= expr; v = x; }
5320288943Sdim              //  { x = x binop expr; v = x; }
5321288943Sdim              //  { x = expr binop x; v = x; }
5322288943Sdim              // Check that the second expression has form v = x.
5323288943Sdim              auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
5324288943Sdim              llvm::FoldingSetNodeID XId, PossibleXId;
5325288943Sdim              Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
5326288943Sdim              PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
5327288943Sdim              IsUpdateExprFound = XId == PossibleXId;
5328288943Sdim              if (IsUpdateExprFound) {
5329288943Sdim                V = BinOp->getLHS();
5330288943Sdim                X = Checker.getX();
5331288943Sdim                E = Checker.getExpr();
5332288943Sdim                UE = Checker.getUpdateExpr();
5333288943Sdim                IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5334288943Sdim                IsPostfixUpdate = false;
5335288943Sdim              }
5336288943Sdim            }
5337288943Sdim          }
5338288943Sdim          if (!IsUpdateExprFound) {
5339288943Sdim            //  { v = x; x = expr; }
5340296417Sdim            auto *FirstExpr = dyn_cast<Expr>(First);
5341296417Sdim            auto *SecondExpr = dyn_cast<Expr>(Second);
5342296417Sdim            if (!FirstExpr || !SecondExpr ||
5343296417Sdim                !(FirstExpr->isInstantiationDependent() ||
5344296417Sdim                  SecondExpr->isInstantiationDependent())) {
5345296417Sdim              auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
5346296417Sdim              if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
5347288943Sdim                ErrorFound = NotAnAssignmentOp;
5348296417Sdim                NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
5349296417Sdim                                                : First->getLocStart();
5350296417Sdim                NoteRange = ErrorRange = FirstBinOp
5351296417Sdim                                             ? FirstBinOp->getSourceRange()
5352288943Sdim                                             : SourceRange(ErrorLoc, ErrorLoc);
5353288943Sdim              } else {
5354296417Sdim                auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
5355296417Sdim                if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
5356296417Sdim                  ErrorFound = NotAnAssignmentOp;
5357296417Sdim                  NoteLoc = ErrorLoc = SecondBinOp
5358296417Sdim                                           ? SecondBinOp->getOperatorLoc()
5359296417Sdim                                           : Second->getLocStart();
5360296417Sdim                  NoteRange = ErrorRange =
5361296417Sdim                      SecondBinOp ? SecondBinOp->getSourceRange()
5362296417Sdim                                  : SourceRange(ErrorLoc, ErrorLoc);
5363288943Sdim                } else {
5364296417Sdim                  auto *PossibleXRHSInFirst =
5365296417Sdim                      FirstBinOp->getRHS()->IgnoreParenImpCasts();
5366296417Sdim                  auto *PossibleXLHSInSecond =
5367296417Sdim                      SecondBinOp->getLHS()->IgnoreParenImpCasts();
5368296417Sdim                  llvm::FoldingSetNodeID X1Id, X2Id;
5369296417Sdim                  PossibleXRHSInFirst->Profile(X1Id, Context,
5370296417Sdim                                               /*Canonical=*/true);
5371296417Sdim                  PossibleXLHSInSecond->Profile(X2Id, Context,
5372296417Sdim                                                /*Canonical=*/true);
5373296417Sdim                  IsUpdateExprFound = X1Id == X2Id;
5374296417Sdim                  if (IsUpdateExprFound) {
5375296417Sdim                    V = FirstBinOp->getLHS();
5376296417Sdim                    X = SecondBinOp->getLHS();
5377296417Sdim                    E = SecondBinOp->getRHS();
5378296417Sdim                    UE = nullptr;
5379296417Sdim                    IsXLHSInRHSPart = false;
5380296417Sdim                    IsPostfixUpdate = true;
5381296417Sdim                  } else {
5382296417Sdim                    ErrorFound = NotASpecificExpression;
5383296417Sdim                    ErrorLoc = FirstBinOp->getExprLoc();
5384296417Sdim                    ErrorRange = FirstBinOp->getSourceRange();
5385296417Sdim                    NoteLoc = SecondBinOp->getLHS()->getExprLoc();
5386296417Sdim                    NoteRange = SecondBinOp->getRHS()->getSourceRange();
5387296417Sdim                  }
5388288943Sdim                }
5389288943Sdim              }
5390288943Sdim            }
5391288943Sdim          }
5392288943Sdim        } else {
5393288943Sdim          NoteLoc = ErrorLoc = Body->getLocStart();
5394288943Sdim          NoteRange = ErrorRange =
5395288943Sdim              SourceRange(Body->getLocStart(), Body->getLocStart());
5396288943Sdim          ErrorFound = NotTwoSubstatements;
5397288943Sdim        }
5398288943Sdim      } else {
5399288943Sdim        NoteLoc = ErrorLoc = Body->getLocStart();
5400288943Sdim        NoteRange = ErrorRange =
5401288943Sdim            SourceRange(Body->getLocStart(), Body->getLocStart());
5402288943Sdim        ErrorFound = NotACompoundStatement;
5403288943Sdim      }
5404288943Sdim      if (ErrorFound != NoError) {
5405288943Sdim        Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
5406288943Sdim            << ErrorRange;
5407288943Sdim        Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
5408288943Sdim        return StmtError();
5409288943Sdim      } else if (CurContext->isDependentContext()) {
5410288943Sdim        UE = V = E = X = nullptr;
5411288943Sdim      }
5412280031Sdim    }
5413280031Sdim  }
5414280031Sdim
5415280031Sdim  getCurFunction()->setHasBranchProtectedScope();
5416280031Sdim
5417280031Sdim  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5418288943Sdim                                    X, V, E, UE, IsXLHSInRHSPart,
5419288943Sdim                                    IsPostfixUpdate);
5420280031Sdim}
5421280031Sdim
5422280031SdimStmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
5423280031Sdim                                            Stmt *AStmt,
5424280031Sdim                                            SourceLocation StartLoc,
5425280031Sdim                                            SourceLocation EndLoc) {
5426296417Sdim  if (!AStmt)
5427296417Sdim    return StmtError();
5428280031Sdim
5429296417Sdim  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5430296417Sdim  // 1.2.2 OpenMP Language Terminology
5431296417Sdim  // Structured block - An executable statement with a single entry at the
5432296417Sdim  // top and a single exit at the bottom.
5433296417Sdim  // The point of exit cannot be a branch out of the structured block.
5434296417Sdim  // longjmp() and throw() must not violate the entry/exit criteria.
5435296417Sdim  CS->getCapturedDecl()->setNothrow();
5436296417Sdim
5437280031Sdim  // OpenMP [2.16, Nesting of Regions]
5438280031Sdim  // If specified, a teams construct must be contained within a target
5439280031Sdim  // construct. That target construct must contain no statements or directives
5440280031Sdim  // outside of the teams construct.
5441280031Sdim  if (DSAStack->hasInnerTeamsRegion()) {
5442280031Sdim    auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true);
5443280031Sdim    bool OMPTeamsFound = true;
5444280031Sdim    if (auto *CS = dyn_cast<CompoundStmt>(S)) {
5445280031Sdim      auto I = CS->body_begin();
5446280031Sdim      while (I != CS->body_end()) {
5447280031Sdim        auto OED = dyn_cast<OMPExecutableDirective>(*I);
5448280031Sdim        if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
5449280031Sdim          OMPTeamsFound = false;
5450280031Sdim          break;
5451280031Sdim        }
5452280031Sdim        ++I;
5453280031Sdim      }
5454280031Sdim      assert(I != CS->body_end() && "Not found statement");
5455280031Sdim      S = *I;
5456280031Sdim    }
5457280031Sdim    if (!OMPTeamsFound) {
5458280031Sdim      Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
5459280031Sdim      Diag(DSAStack->getInnerTeamsRegionLoc(),
5460280031Sdim           diag::note_omp_nested_teams_construct_here);
5461280031Sdim      Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
5462280031Sdim          << isa<OMPExecutableDirective>(S);
5463280031Sdim      return StmtError();
5464280031Sdim    }
5465280031Sdim  }
5466280031Sdim
5467280031Sdim  getCurFunction()->setHasBranchProtectedScope();
5468280031Sdim
5469280031Sdim  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5470280031Sdim}
5471280031Sdim
5472296417SdimStmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
5473296417Sdim                                                Stmt *AStmt,
5474296417Sdim                                                SourceLocation StartLoc,
5475296417Sdim                                                SourceLocation EndLoc) {
5476296417Sdim  if (!AStmt)
5477296417Sdim    return StmtError();
5478296417Sdim
5479296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5480296417Sdim
5481296417Sdim  getCurFunction()->setHasBranchProtectedScope();
5482296417Sdim
5483296417Sdim  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
5484296417Sdim                                        AStmt);
5485296417Sdim}
5486296417Sdim
5487280031SdimStmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
5488280031Sdim                                           Stmt *AStmt, SourceLocation StartLoc,
5489280031Sdim                                           SourceLocation EndLoc) {
5490296417Sdim  if (!AStmt)
5491296417Sdim    return StmtError();
5492296417Sdim
5493280031Sdim  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5494280031Sdim  // 1.2.2 OpenMP Language Terminology
5495280031Sdim  // Structured block - An executable statement with a single entry at the
5496280031Sdim  // top and a single exit at the bottom.
5497280031Sdim  // The point of exit cannot be a branch out of the structured block.
5498280031Sdim  // longjmp() and throw() must not violate the entry/exit criteria.
5499280031Sdim  CS->getCapturedDecl()->setNothrow();
5500280031Sdim
5501280031Sdim  getCurFunction()->setHasBranchProtectedScope();
5502280031Sdim
5503280031Sdim  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5504280031Sdim}
5505280031Sdim
5506288943SdimStmtResult
5507288943SdimSema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
5508288943Sdim                                            SourceLocation EndLoc,
5509288943Sdim                                            OpenMPDirectiveKind CancelRegion) {
5510288943Sdim  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
5511288943Sdim      CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
5512288943Sdim    Diag(StartLoc, diag::err_omp_wrong_cancel_region)
5513288943Sdim        << getOpenMPDirectiveName(CancelRegion);
5514288943Sdim    return StmtError();
5515288943Sdim  }
5516288943Sdim  if (DSAStack->isParentNowaitRegion()) {
5517288943Sdim    Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
5518288943Sdim    return StmtError();
5519288943Sdim  }
5520288943Sdim  if (DSAStack->isParentOrderedRegion()) {
5521288943Sdim    Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
5522288943Sdim    return StmtError();
5523288943Sdim  }
5524288943Sdim  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
5525288943Sdim                                               CancelRegion);
5526288943Sdim}
5527288943Sdim
5528296417SdimStmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
5529296417Sdim                                            SourceLocation StartLoc,
5530288943Sdim                                            SourceLocation EndLoc,
5531288943Sdim                                            OpenMPDirectiveKind CancelRegion) {
5532288943Sdim  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
5533288943Sdim      CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
5534288943Sdim    Diag(StartLoc, diag::err_omp_wrong_cancel_region)
5535288943Sdim        << getOpenMPDirectiveName(CancelRegion);
5536288943Sdim    return StmtError();
5537288943Sdim  }
5538288943Sdim  if (DSAStack->isParentNowaitRegion()) {
5539288943Sdim    Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
5540288943Sdim    return StmtError();
5541288943Sdim  }
5542288943Sdim  if (DSAStack->isParentOrderedRegion()) {
5543288943Sdim    Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
5544288943Sdim    return StmtError();
5545288943Sdim  }
5546296417Sdim  DSAStack->setParentCancelRegion(/*Cancel=*/true);
5547296417Sdim  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
5548296417Sdim                                    CancelRegion);
5549288943Sdim}
5550288943Sdim
5551296417Sdimstatic bool checkGrainsizeNumTasksClauses(Sema &S,
5552296417Sdim                                          ArrayRef<OMPClause *> Clauses) {
5553296417Sdim  OMPClause *PrevClause = nullptr;
5554296417Sdim  bool ErrorFound = false;
5555296417Sdim  for (auto *C : Clauses) {
5556296417Sdim    if (C->getClauseKind() == OMPC_grainsize ||
5557296417Sdim        C->getClauseKind() == OMPC_num_tasks) {
5558296417Sdim      if (!PrevClause)
5559296417Sdim        PrevClause = C;
5560296417Sdim      else if (PrevClause->getClauseKind() != C->getClauseKind()) {
5561296417Sdim        S.Diag(C->getLocStart(),
5562296417Sdim               diag::err_omp_grainsize_num_tasks_mutually_exclusive)
5563296417Sdim            << getOpenMPClauseName(C->getClauseKind())
5564296417Sdim            << getOpenMPClauseName(PrevClause->getClauseKind());
5565296417Sdim        S.Diag(PrevClause->getLocStart(),
5566296417Sdim               diag::note_omp_previous_grainsize_num_tasks)
5567296417Sdim            << getOpenMPClauseName(PrevClause->getClauseKind());
5568296417Sdim        ErrorFound = true;
5569296417Sdim      }
5570296417Sdim    }
5571296417Sdim  }
5572296417Sdim  return ErrorFound;
5573296417Sdim}
5574296417Sdim
5575296417SdimStmtResult Sema::ActOnOpenMPTaskLoopDirective(
5576296417Sdim    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5577296417Sdim    SourceLocation EndLoc,
5578296417Sdim    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
5579296417Sdim  if (!AStmt)
5580296417Sdim    return StmtError();
5581296417Sdim
5582296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5583296417Sdim  OMPLoopDirective::HelperExprs B;
5584296417Sdim  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5585296417Sdim  // define the nested loops number.
5586296417Sdim  unsigned NestedLoopCount =
5587296417Sdim      CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
5588296417Sdim                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
5589296417Sdim                      VarsWithImplicitDSA, B);
5590296417Sdim  if (NestedLoopCount == 0)
5591296417Sdim    return StmtError();
5592296417Sdim
5593296417Sdim  assert((CurContext->isDependentContext() || B.builtAll()) &&
5594296417Sdim         "omp for loop exprs were not built");
5595296417Sdim
5596296417Sdim  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
5597296417Sdim  // The grainsize clause and num_tasks clause are mutually exclusive and may
5598296417Sdim  // not appear on the same taskloop directive.
5599296417Sdim  if (checkGrainsizeNumTasksClauses(*this, Clauses))
5600296417Sdim    return StmtError();
5601296417Sdim
5602296417Sdim  getCurFunction()->setHasBranchProtectedScope();
5603296417Sdim  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
5604296417Sdim                                      NestedLoopCount, Clauses, AStmt, B);
5605296417Sdim}
5606296417Sdim
5607296417SdimStmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
5608296417Sdim    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5609296417Sdim    SourceLocation EndLoc,
5610296417Sdim    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
5611296417Sdim  if (!AStmt)
5612296417Sdim    return StmtError();
5613296417Sdim
5614296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5615296417Sdim  OMPLoopDirective::HelperExprs B;
5616296417Sdim  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5617296417Sdim  // define the nested loops number.
5618296417Sdim  unsigned NestedLoopCount =
5619296417Sdim      CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
5620296417Sdim                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
5621296417Sdim                      VarsWithImplicitDSA, B);
5622296417Sdim  if (NestedLoopCount == 0)
5623296417Sdim    return StmtError();
5624296417Sdim
5625296417Sdim  assert((CurContext->isDependentContext() || B.builtAll()) &&
5626296417Sdim         "omp for loop exprs were not built");
5627296417Sdim
5628296417Sdim  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
5629296417Sdim  // The grainsize clause and num_tasks clause are mutually exclusive and may
5630296417Sdim  // not appear on the same taskloop directive.
5631296417Sdim  if (checkGrainsizeNumTasksClauses(*this, Clauses))
5632296417Sdim    return StmtError();
5633296417Sdim
5634296417Sdim  getCurFunction()->setHasBranchProtectedScope();
5635296417Sdim  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
5636296417Sdim                                          NestedLoopCount, Clauses, AStmt, B);
5637296417Sdim}
5638296417Sdim
5639296417SdimStmtResult Sema::ActOnOpenMPDistributeDirective(
5640296417Sdim    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5641296417Sdim    SourceLocation EndLoc,
5642296417Sdim    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
5643296417Sdim  if (!AStmt)
5644296417Sdim    return StmtError();
5645296417Sdim
5646296417Sdim  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5647296417Sdim  OMPLoopDirective::HelperExprs B;
5648296417Sdim  // In presence of clause 'collapse' with number of loops, it will
5649296417Sdim  // define the nested loops number.
5650296417Sdim  unsigned NestedLoopCount =
5651296417Sdim      CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
5652296417Sdim                      nullptr /*ordered not a clause on distribute*/, AStmt,
5653296417Sdim                      *this, *DSAStack, VarsWithImplicitDSA, B);
5654296417Sdim  if (NestedLoopCount == 0)
5655296417Sdim    return StmtError();
5656296417Sdim
5657296417Sdim  assert((CurContext->isDependentContext() || B.builtAll()) &&
5658296417Sdim         "omp for loop exprs were not built");
5659296417Sdim
5660296417Sdim  getCurFunction()->setHasBranchProtectedScope();
5661296417Sdim  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
5662296417Sdim                                        NestedLoopCount, Clauses, AStmt, B);
5663296417Sdim}
5664296417Sdim
5665276479SdimOMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
5666276479Sdim                                             SourceLocation StartLoc,
5667276479Sdim                                             SourceLocation LParenLoc,
5668276479Sdim                                             SourceLocation EndLoc) {
5669276479Sdim  OMPClause *Res = nullptr;
5670261991Sdim  switch (Kind) {
5671276479Sdim  case OMPC_final:
5672276479Sdim    Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
5673276479Sdim    break;
5674276479Sdim  case OMPC_num_threads:
5675276479Sdim    Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
5676276479Sdim    break;
5677276479Sdim  case OMPC_safelen:
5678276479Sdim    Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
5679276479Sdim    break;
5680296417Sdim  case OMPC_simdlen:
5681296417Sdim    Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
5682296417Sdim    break;
5683276479Sdim  case OMPC_collapse:
5684276479Sdim    Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
5685276479Sdim    break;
5686296417Sdim  case OMPC_ordered:
5687296417Sdim    Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
5688296417Sdim    break;
5689296417Sdim  case OMPC_device:
5690296417Sdim    Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
5691296417Sdim    break;
5692296417Sdim  case OMPC_num_teams:
5693296417Sdim    Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
5694296417Sdim    break;
5695296417Sdim  case OMPC_thread_limit:
5696296417Sdim    Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
5697296417Sdim    break;
5698296417Sdim  case OMPC_priority:
5699296417Sdim    Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
5700296417Sdim    break;
5701296417Sdim  case OMPC_grainsize:
5702296417Sdim    Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
5703296417Sdim    break;
5704296417Sdim  case OMPC_num_tasks:
5705296417Sdim    Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
5706296417Sdim    break;
5707296417Sdim  case OMPC_hint:
5708296417Sdim    Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
5709296417Sdim    break;
5710296417Sdim  case OMPC_if:
5711261991Sdim  case OMPC_default:
5712276479Sdim  case OMPC_proc_bind:
5713276479Sdim  case OMPC_schedule:
5714276479Sdim  case OMPC_private:
5715276479Sdim  case OMPC_firstprivate:
5716276479Sdim  case OMPC_lastprivate:
5717276479Sdim  case OMPC_shared:
5718276479Sdim  case OMPC_reduction:
5719276479Sdim  case OMPC_linear:
5720276479Sdim  case OMPC_aligned:
5721276479Sdim  case OMPC_copyin:
5722276479Sdim  case OMPC_copyprivate:
5723276479Sdim  case OMPC_nowait:
5724276479Sdim  case OMPC_untied:
5725276479Sdim  case OMPC_mergeable:
5726276479Sdim  case OMPC_threadprivate:
5727276479Sdim  case OMPC_flush:
5728280031Sdim  case OMPC_read:
5729280031Sdim  case OMPC_write:
5730280031Sdim  case OMPC_update:
5731280031Sdim  case OMPC_capture:
5732280031Sdim  case OMPC_seq_cst:
5733288943Sdim  case OMPC_depend:
5734296417Sdim  case OMPC_threads:
5735296417Sdim  case OMPC_simd:
5736296417Sdim  case OMPC_map:
5737296417Sdim  case OMPC_nogroup:
5738276479Sdim  case OMPC_unknown:
5739276479Sdim    llvm_unreachable("Clause is not allowed.");
5740276479Sdim  }
5741276479Sdim  return Res;
5742276479Sdim}
5743276479Sdim
5744296417SdimOMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
5745296417Sdim                                     Expr *Condition, SourceLocation StartLoc,
5746276479Sdim                                     SourceLocation LParenLoc,
5747296417Sdim                                     SourceLocation NameModifierLoc,
5748296417Sdim                                     SourceLocation ColonLoc,
5749276479Sdim                                     SourceLocation EndLoc) {
5750276479Sdim  Expr *ValExpr = Condition;
5751276479Sdim  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
5752276479Sdim      !Condition->isInstantiationDependent() &&
5753276479Sdim      !Condition->containsUnexpandedParameterPack()) {
5754276479Sdim    ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
5755276479Sdim                                           Condition->getExprLoc(), Condition);
5756276479Sdim    if (Val.isInvalid())
5757276479Sdim      return nullptr;
5758276479Sdim
5759276479Sdim    ValExpr = Val.get();
5760276479Sdim  }
5761276479Sdim
5762296417Sdim  return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,
5763296417Sdim                                   NameModifierLoc, ColonLoc, EndLoc);
5764276479Sdim}
5765276479Sdim
5766276479SdimOMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
5767276479Sdim                                        SourceLocation StartLoc,
5768276479Sdim                                        SourceLocation LParenLoc,
5769276479Sdim                                        SourceLocation EndLoc) {
5770276479Sdim  Expr *ValExpr = Condition;
5771276479Sdim  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
5772276479Sdim      !Condition->isInstantiationDependent() &&
5773276479Sdim      !Condition->containsUnexpandedParameterPack()) {
5774276479Sdim    ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
5775276479Sdim                                           Condition->getExprLoc(), Condition);
5776276479Sdim    if (Val.isInvalid())
5777276479Sdim      return nullptr;
5778276479Sdim
5779276479Sdim    ValExpr = Val.get();
5780276479Sdim  }
5781276479Sdim
5782276479Sdim  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
5783276479Sdim}
5784276479SdimExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
5785276479Sdim                                                        Expr *Op) {
5786276479Sdim  if (!Op)
5787276479Sdim    return ExprError();
5788276479Sdim
5789276479Sdim  class IntConvertDiagnoser : public ICEConvertDiagnoser {
5790276479Sdim  public:
5791276479Sdim    IntConvertDiagnoser()
5792276479Sdim        : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
5793276479Sdim    SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
5794276479Sdim                                         QualType T) override {
5795276479Sdim      return S.Diag(Loc, diag::err_omp_not_integral) << T;
5796276479Sdim    }
5797276479Sdim    SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
5798276479Sdim                                             QualType T) override {
5799276479Sdim      return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
5800276479Sdim    }
5801276479Sdim    SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
5802276479Sdim                                               QualType T,
5803276479Sdim                                               QualType ConvTy) override {
5804276479Sdim      return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
5805276479Sdim    }
5806276479Sdim    SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
5807276479Sdim                                           QualType ConvTy) override {
5808276479Sdim      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
5809276479Sdim             << ConvTy->isEnumeralType() << ConvTy;
5810276479Sdim    }
5811276479Sdim    SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
5812276479Sdim                                            QualType T) override {
5813276479Sdim      return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
5814276479Sdim    }
5815276479Sdim    SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
5816276479Sdim                                        QualType ConvTy) override {
5817276479Sdim      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
5818276479Sdim             << ConvTy->isEnumeralType() << ConvTy;
5819276479Sdim    }
5820276479Sdim    SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
5821276479Sdim                                             QualType) override {
5822276479Sdim      llvm_unreachable("conversion functions are permitted");
5823276479Sdim    }
5824276479Sdim  } ConvertDiagnoser;
5825276479Sdim  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
5826276479Sdim}
5827276479Sdim
5828296417Sdimstatic bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
5829296417Sdim                                      OpenMPClauseKind CKind,
5830296417Sdim                                      bool StrictlyPositive) {
5831296417Sdim  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
5832296417Sdim      !ValExpr->isInstantiationDependent()) {
5833296417Sdim    SourceLocation Loc = ValExpr->getExprLoc();
5834296417Sdim    ExprResult Value =
5835296417Sdim        SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
5836296417Sdim    if (Value.isInvalid())
5837296417Sdim      return false;
5838296417Sdim
5839296417Sdim    ValExpr = Value.get();
5840296417Sdim    // The expression must evaluate to a non-negative integer value.
5841296417Sdim    llvm::APSInt Result;
5842296417Sdim    if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
5843296417Sdim        Result.isSigned() &&
5844296417Sdim        !((!StrictlyPositive && Result.isNonNegative()) ||
5845296417Sdim          (StrictlyPositive && Result.isStrictlyPositive()))) {
5846296417Sdim      SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
5847296417Sdim          << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
5848296417Sdim          << ValExpr->getSourceRange();
5849296417Sdim      return false;
5850296417Sdim    }
5851296417Sdim  }
5852296417Sdim  return true;
5853296417Sdim}
5854296417Sdim
5855276479SdimOMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
5856276479Sdim                                             SourceLocation StartLoc,
5857276479Sdim                                             SourceLocation LParenLoc,
5858276479Sdim                                             SourceLocation EndLoc) {
5859276479Sdim  Expr *ValExpr = NumThreads;
5860276479Sdim
5861296417Sdim  // OpenMP [2.5, Restrictions]
5862296417Sdim  //  The num_threads expression must evaluate to a positive integer value.
5863296417Sdim  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
5864296417Sdim                                 /*StrictlyPositive=*/true))
5865296417Sdim    return nullptr;
5866276479Sdim
5867276479Sdim  return new (Context)
5868276479Sdim      OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
5869276479Sdim}
5870276479Sdim
5871276479SdimExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
5872296417Sdim                                                       OpenMPClauseKind CKind,
5873296417Sdim                                                       bool StrictlyPositive) {
5874276479Sdim  if (!E)
5875276479Sdim    return ExprError();
5876276479Sdim  if (E->isValueDependent() || E->isTypeDependent() ||
5877276479Sdim      E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5878276479Sdim    return E;
5879276479Sdim  llvm::APSInt Result;
5880276479Sdim  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
5881276479Sdim  if (ICE.isInvalid())
5882276479Sdim    return ExprError();
5883296417Sdim  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
5884296417Sdim      (!StrictlyPositive && !Result.isNonNegative())) {
5885276479Sdim    Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
5886296417Sdim        << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
5887296417Sdim        << E->getSourceRange();
5888276479Sdim    return ExprError();
5889276479Sdim  }
5890280031Sdim  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
5891280031Sdim    Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
5892280031Sdim        << E->getSourceRange();
5893280031Sdim    return ExprError();
5894280031Sdim  }
5895296417Sdim  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
5896296417Sdim    DSAStack->setAssociatedLoops(Result.getExtValue());
5897296417Sdim  else if (CKind == OMPC_ordered)
5898296417Sdim    DSAStack->setAssociatedLoops(Result.getExtValue());
5899276479Sdim  return ICE;
5900276479Sdim}
5901276479Sdim
5902276479SdimOMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
5903276479Sdim                                          SourceLocation LParenLoc,
5904276479Sdim                                          SourceLocation EndLoc) {
5905276479Sdim  // OpenMP [2.8.1, simd construct, Description]
5906276479Sdim  // The parameter of the safelen clause must be a constant
5907276479Sdim  // positive integer expression.
5908276479Sdim  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
5909276479Sdim  if (Safelen.isInvalid())
5910276479Sdim    return nullptr;
5911276479Sdim  return new (Context)
5912276479Sdim      OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
5913276479Sdim}
5914276479Sdim
5915296417SdimOMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
5916296417Sdim                                          SourceLocation LParenLoc,
5917296417Sdim                                          SourceLocation EndLoc) {
5918296417Sdim  // OpenMP [2.8.1, simd construct, Description]
5919296417Sdim  // The parameter of the simdlen clause must be a constant
5920296417Sdim  // positive integer expression.
5921296417Sdim  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
5922296417Sdim  if (Simdlen.isInvalid())
5923296417Sdim    return nullptr;
5924296417Sdim  return new (Context)
5925296417Sdim      OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
5926296417Sdim}
5927296417Sdim
5928276479SdimOMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
5929276479Sdim                                           SourceLocation StartLoc,
5930276479Sdim                                           SourceLocation LParenLoc,
5931276479Sdim                                           SourceLocation EndLoc) {
5932276479Sdim  // OpenMP [2.7.1, loop construct, Description]
5933276479Sdim  // OpenMP [2.8.1, simd construct, Description]
5934276479Sdim  // OpenMP [2.9.6, distribute construct, Description]
5935276479Sdim  // The parameter of the collapse clause must be a constant
5936276479Sdim  // positive integer expression.
5937276479Sdim  ExprResult NumForLoopsResult =
5938276479Sdim      VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
5939276479Sdim  if (NumForLoopsResult.isInvalid())
5940276479Sdim    return nullptr;
5941276479Sdim  return new (Context)
5942276479Sdim      OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
5943276479Sdim}
5944276479Sdim
5945296417SdimOMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
5946296417Sdim                                          SourceLocation EndLoc,
5947296417Sdim                                          SourceLocation LParenLoc,
5948296417Sdim                                          Expr *NumForLoops) {
5949296417Sdim  // OpenMP [2.7.1, loop construct, Description]
5950296417Sdim  // OpenMP [2.8.1, simd construct, Description]
5951296417Sdim  // OpenMP [2.9.6, distribute construct, Description]
5952296417Sdim  // The parameter of the ordered clause must be a constant
5953296417Sdim  // positive integer expression if any.
5954296417Sdim  if (NumForLoops && LParenLoc.isValid()) {
5955296417Sdim    ExprResult NumForLoopsResult =
5956296417Sdim        VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
5957296417Sdim    if (NumForLoopsResult.isInvalid())
5958296417Sdim      return nullptr;
5959296417Sdim    NumForLoops = NumForLoopsResult.get();
5960296417Sdim  } else
5961296417Sdim    NumForLoops = nullptr;
5962296417Sdim  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops);
5963296417Sdim  return new (Context)
5964296417Sdim      OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc);
5965296417Sdim}
5966296417Sdim
5967276479SdimOMPClause *Sema::ActOnOpenMPSimpleClause(
5968276479Sdim    OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
5969276479Sdim    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
5970276479Sdim  OMPClause *Res = nullptr;
5971276479Sdim  switch (Kind) {
5972276479Sdim  case OMPC_default:
5973261991Sdim    Res =
5974276479Sdim        ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
5975276479Sdim                                 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
5976261991Sdim    break;
5977276479Sdim  case OMPC_proc_bind:
5978276479Sdim    Res = ActOnOpenMPProcBindClause(
5979276479Sdim        static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
5980276479Sdim        LParenLoc, EndLoc);
5981276479Sdim    break;
5982276479Sdim  case OMPC_if:
5983276479Sdim  case OMPC_final:
5984276479Sdim  case OMPC_num_threads:
5985276479Sdim  case OMPC_safelen:
5986296417Sdim  case OMPC_simdlen:
5987276479Sdim  case OMPC_collapse:
5988276479Sdim  case OMPC_schedule:
5989261991Sdim  case OMPC_private:
5990261991Sdim  case OMPC_firstprivate:
5991276479Sdim  case OMPC_lastprivate:
5992261991Sdim  case OMPC_shared:
5993276479Sdim  case OMPC_reduction:
5994276479Sdim  case OMPC_linear:
5995276479Sdim  case OMPC_aligned:
5996276479Sdim  case OMPC_copyin:
5997276479Sdim  case OMPC_copyprivate:
5998276479Sdim  case OMPC_ordered:
5999276479Sdim  case OMPC_nowait:
6000276479Sdim  case OMPC_untied:
6001276479Sdim  case OMPC_mergeable:
6002261991Sdim  case OMPC_threadprivate:
6003276479Sdim  case OMPC_flush:
6004280031Sdim  case OMPC_read:
6005280031Sdim  case OMPC_write:
6006280031Sdim  case OMPC_update:
6007280031Sdim  case OMPC_capture:
6008280031Sdim  case OMPC_seq_cst:
6009288943Sdim  case OMPC_depend:
6010296417Sdim  case OMPC_device:
6011296417Sdim  case OMPC_threads:
6012296417Sdim  case OMPC_simd:
6013296417Sdim  case OMPC_map:
6014296417Sdim  case OMPC_num_teams:
6015296417Sdim  case OMPC_thread_limit:
6016296417Sdim  case OMPC_priority:
6017296417Sdim  case OMPC_grainsize:
6018296417Sdim  case OMPC_nogroup:
6019296417Sdim  case OMPC_num_tasks:
6020296417Sdim  case OMPC_hint:
6021261991Sdim  case OMPC_unknown:
6022261991Sdim    llvm_unreachable("Clause is not allowed.");
6023261991Sdim  }
6024261991Sdim  return Res;
6025261991Sdim}
6026261991Sdim
6027296417Sdimstatic std::string
6028296417SdimgetListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
6029296417Sdim                        ArrayRef<unsigned> Exclude = llvm::None) {
6030296417Sdim  std::string Values;
6031296417Sdim  unsigned Bound = Last >= 2 ? Last - 2 : 0;
6032296417Sdim  unsigned Skipped = Exclude.size();
6033296417Sdim  auto S = Exclude.begin(), E = Exclude.end();
6034296417Sdim  for (unsigned i = First; i < Last; ++i) {
6035296417Sdim    if (std::find(S, E, i) != E) {
6036296417Sdim      --Skipped;
6037296417Sdim      continue;
6038296417Sdim    }
6039296417Sdim    Values += "'";
6040296417Sdim    Values += getOpenMPSimpleClauseTypeName(K, i);
6041296417Sdim    Values += "'";
6042296417Sdim    if (i == Bound - Skipped)
6043296417Sdim      Values += " or ";
6044296417Sdim    else if (i != Bound + 1 - Skipped)
6045296417Sdim      Values += ", ";
6046296417Sdim  }
6047296417Sdim  return Values;
6048296417Sdim}
6049296417Sdim
6050261991SdimOMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
6051261991Sdim                                          SourceLocation KindKwLoc,
6052261991Sdim                                          SourceLocation StartLoc,
6053261991Sdim                                          SourceLocation LParenLoc,
6054261991Sdim                                          SourceLocation EndLoc) {
6055261991Sdim  if (Kind == OMPC_DEFAULT_unknown) {
6056276479Sdim    static_assert(OMPC_DEFAULT_unknown > 0,
6057276479Sdim                  "OMPC_DEFAULT_unknown not greater than 0");
6058261991Sdim    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
6059296417Sdim        << getListOfPossibleValues(OMPC_default, /*First=*/0,
6060296417Sdim                                   /*Last=*/OMPC_DEFAULT_unknown)
6061296417Sdim        << getOpenMPClauseName(OMPC_default);
6062276479Sdim    return nullptr;
6063261991Sdim  }
6064261991Sdim  switch (Kind) {
6065261991Sdim  case OMPC_DEFAULT_none:
6066276479Sdim    DSAStack->setDefaultDSANone(KindKwLoc);
6067261991Sdim    break;
6068261991Sdim  case OMPC_DEFAULT_shared:
6069276479Sdim    DSAStack->setDefaultDSAShared(KindKwLoc);
6070261991Sdim    break;
6071276479Sdim  case OMPC_DEFAULT_unknown:
6072276479Sdim    llvm_unreachable("Clause kind is not allowed.");
6073261991Sdim    break;
6074261991Sdim  }
6075276479Sdim  return new (Context)
6076276479Sdim      OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
6077261991Sdim}
6078261991Sdim
6079276479SdimOMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
6080276479Sdim                                           SourceLocation KindKwLoc,
6081276479Sdim                                           SourceLocation StartLoc,
6082276479Sdim                                           SourceLocation LParenLoc,
6083276479Sdim                                           SourceLocation EndLoc) {
6084276479Sdim  if (Kind == OMPC_PROC_BIND_unknown) {
6085276479Sdim    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
6086296417Sdim        << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
6087296417Sdim                                   /*Last=*/OMPC_PROC_BIND_unknown)
6088296417Sdim        << getOpenMPClauseName(OMPC_proc_bind);
6089276479Sdim    return nullptr;
6090276479Sdim  }
6091276479Sdim  return new (Context)
6092276479Sdim      OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
6093276479Sdim}
6094276479Sdim
6095276479SdimOMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
6096296417Sdim    OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
6097276479Sdim    SourceLocation StartLoc, SourceLocation LParenLoc,
6098296417Sdim    ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
6099276479Sdim    SourceLocation EndLoc) {
6100276479Sdim  OMPClause *Res = nullptr;
6101276479Sdim  switch (Kind) {
6102276479Sdim  case OMPC_schedule:
6103296417Sdim    enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
6104296417Sdim    assert(Argument.size() == NumberOfElements &&
6105296417Sdim           ArgumentLoc.size() == NumberOfElements);
6106276479Sdim    Res = ActOnOpenMPScheduleClause(
6107296417Sdim        static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
6108296417Sdim        static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
6109296417Sdim        static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
6110296417Sdim        StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
6111296417Sdim        ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
6112276479Sdim    break;
6113276479Sdim  case OMPC_if:
6114296417Sdim    assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
6115296417Sdim    Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
6116296417Sdim                              Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
6117296417Sdim                              DelimLoc, EndLoc);
6118296417Sdim    break;
6119276479Sdim  case OMPC_final:
6120276479Sdim  case OMPC_num_threads:
6121276479Sdim  case OMPC_safelen:
6122296417Sdim  case OMPC_simdlen:
6123276479Sdim  case OMPC_collapse:
6124276479Sdim  case OMPC_default:
6125276479Sdim  case OMPC_proc_bind:
6126276479Sdim  case OMPC_private:
6127276479Sdim  case OMPC_firstprivate:
6128276479Sdim  case OMPC_lastprivate:
6129276479Sdim  case OMPC_shared:
6130276479Sdim  case OMPC_reduction:
6131276479Sdim  case OMPC_linear:
6132276479Sdim  case OMPC_aligned:
6133276479Sdim  case OMPC_copyin:
6134276479Sdim  case OMPC_copyprivate:
6135276479Sdim  case OMPC_ordered:
6136276479Sdim  case OMPC_nowait:
6137276479Sdim  case OMPC_untied:
6138276479Sdim  case OMPC_mergeable:
6139276479Sdim  case OMPC_threadprivate:
6140276479Sdim  case OMPC_flush:
6141280031Sdim  case OMPC_read:
6142280031Sdim  case OMPC_write:
6143280031Sdim  case OMPC_update:
6144280031Sdim  case OMPC_capture:
6145280031Sdim  case OMPC_seq_cst:
6146288943Sdim  case OMPC_depend:
6147296417Sdim  case OMPC_device:
6148296417Sdim  case OMPC_threads:
6149296417Sdim  case OMPC_simd:
6150296417Sdim  case OMPC_map:
6151296417Sdim  case OMPC_num_teams:
6152296417Sdim  case OMPC_thread_limit:
6153296417Sdim  case OMPC_priority:
6154296417Sdim  case OMPC_grainsize:
6155296417Sdim  case OMPC_nogroup:
6156296417Sdim  case OMPC_num_tasks:
6157296417Sdim  case OMPC_hint:
6158276479Sdim  case OMPC_unknown:
6159276479Sdim    llvm_unreachable("Clause is not allowed.");
6160276479Sdim  }
6161276479Sdim  return Res;
6162276479Sdim}
6163276479Sdim
6164296417Sdimstatic bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
6165296417Sdim                                   OpenMPScheduleClauseModifier M2,
6166296417Sdim                                   SourceLocation M1Loc, SourceLocation M2Loc) {
6167296417Sdim  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
6168296417Sdim    SmallVector<unsigned, 2> Excluded;
6169296417Sdim    if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
6170296417Sdim      Excluded.push_back(M2);
6171296417Sdim    if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
6172296417Sdim      Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
6173296417Sdim    if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
6174296417Sdim      Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
6175296417Sdim    S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
6176296417Sdim        << getListOfPossibleValues(OMPC_schedule,
6177296417Sdim                                   /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
6178296417Sdim                                   /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
6179296417Sdim                                   Excluded)
6180296417Sdim        << getOpenMPClauseName(OMPC_schedule);
6181296417Sdim    return true;
6182296417Sdim  }
6183296417Sdim  return false;
6184296417Sdim}
6185296417Sdim
6186276479SdimOMPClause *Sema::ActOnOpenMPScheduleClause(
6187296417Sdim    OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
6188276479Sdim    OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
6189296417Sdim    SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
6190296417Sdim    SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
6191296417Sdim  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
6192296417Sdim      checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
6193296417Sdim    return nullptr;
6194296417Sdim  // OpenMP, 2.7.1, Loop Construct, Restrictions
6195296417Sdim  // Either the monotonic modifier or the nonmonotonic modifier can be specified
6196296417Sdim  // but not both.
6197296417Sdim  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
6198296417Sdim      (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
6199296417Sdim       M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
6200296417Sdim      (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
6201296417Sdim       M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
6202296417Sdim    Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
6203296417Sdim        << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
6204296417Sdim        << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
6205296417Sdim    return nullptr;
6206296417Sdim  }
6207276479Sdim  if (Kind == OMPC_SCHEDULE_unknown) {
6208276479Sdim    std::string Values;
6209296417Sdim    if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
6210296417Sdim      unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
6211296417Sdim      Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
6212296417Sdim                                       /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
6213296417Sdim                                       Exclude);
6214296417Sdim    } else {
6215296417Sdim      Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
6216296417Sdim                                       /*Last=*/OMPC_SCHEDULE_unknown);
6217276479Sdim    }
6218276479Sdim    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
6219276479Sdim        << Values << getOpenMPClauseName(OMPC_schedule);
6220276479Sdim    return nullptr;
6221276479Sdim  }
6222296417Sdim  // OpenMP, 2.7.1, Loop Construct, Restrictions
6223296417Sdim  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
6224296417Sdim  // schedule(guided).
6225296417Sdim  if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
6226296417Sdim       M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
6227296417Sdim      Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
6228296417Sdim    Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
6229296417Sdim         diag::err_omp_schedule_nonmonotonic_static);
6230296417Sdim    return nullptr;
6231296417Sdim  }
6232276479Sdim  Expr *ValExpr = ChunkSize;
6233288943Sdim  Expr *HelperValExpr = nullptr;
6234276479Sdim  if (ChunkSize) {
6235276479Sdim    if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
6236276479Sdim        !ChunkSize->isInstantiationDependent() &&
6237276479Sdim        !ChunkSize->containsUnexpandedParameterPack()) {
6238276479Sdim      SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
6239276479Sdim      ExprResult Val =
6240276479Sdim          PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
6241276479Sdim      if (Val.isInvalid())
6242276479Sdim        return nullptr;
6243276479Sdim
6244276479Sdim      ValExpr = Val.get();
6245276479Sdim
6246276479Sdim      // OpenMP [2.7.1, Restrictions]
6247276479Sdim      //  chunk_size must be a loop invariant integer expression with a positive
6248276479Sdim      //  value.
6249276479Sdim      llvm::APSInt Result;
6250288943Sdim      if (ValExpr->isIntegerConstantExpr(Result, Context)) {
6251288943Sdim        if (Result.isSigned() && !Result.isStrictlyPositive()) {
6252288943Sdim          Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
6253296417Sdim              << "schedule" << 1 << ChunkSize->getSourceRange();
6254288943Sdim          return nullptr;
6255288943Sdim        }
6256288943Sdim      } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) {
6257288943Sdim        auto *ImpVar = buildVarDecl(*this, ChunkSize->getExprLoc(),
6258288943Sdim                                    ChunkSize->getType(), ".chunk.");
6259288943Sdim        auto *ImpVarRef = buildDeclRefExpr(*this, ImpVar, ChunkSize->getType(),
6260288943Sdim                                           ChunkSize->getExprLoc(),
6261288943Sdim                                           /*RefersToCapture=*/true);
6262288943Sdim        HelperValExpr = ImpVarRef;
6263276479Sdim      }
6264276479Sdim    }
6265276479Sdim  }
6266276479Sdim
6267296417Sdim  return new (Context)
6268296417Sdim      OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
6269296417Sdim                        ValExpr, HelperValExpr, M1, M1Loc, M2, M2Loc);
6270276479Sdim}
6271276479Sdim
6272276479SdimOMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
6273276479Sdim                                   SourceLocation StartLoc,
6274276479Sdim                                   SourceLocation EndLoc) {
6275276479Sdim  OMPClause *Res = nullptr;
6276276479Sdim  switch (Kind) {
6277276479Sdim  case OMPC_ordered:
6278276479Sdim    Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
6279276479Sdim    break;
6280276479Sdim  case OMPC_nowait:
6281276479Sdim    Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
6282276479Sdim    break;
6283276479Sdim  case OMPC_untied:
6284276479Sdim    Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
6285276479Sdim    break;
6286276479Sdim  case OMPC_mergeable:
6287276479Sdim    Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
6288276479Sdim    break;
6289280031Sdim  case OMPC_read:
6290280031Sdim    Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
6291280031Sdim    break;
6292280031Sdim  case OMPC_write:
6293280031Sdim    Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
6294280031Sdim    break;
6295280031Sdim  case OMPC_update:
6296280031Sdim    Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
6297280031Sdim    break;
6298280031Sdim  case OMPC_capture:
6299280031Sdim    Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
6300280031Sdim    break;
6301280031Sdim  case OMPC_seq_cst:
6302280031Sdim    Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
6303280031Sdim    break;
6304296417Sdim  case OMPC_threads:
6305296417Sdim    Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
6306296417Sdim    break;
6307296417Sdim  case OMPC_simd:
6308296417Sdim    Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
6309296417Sdim    break;
6310296417Sdim  case OMPC_nogroup:
6311296417Sdim    Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
6312296417Sdim    break;
6313276479Sdim  case OMPC_if:
6314276479Sdim  case OMPC_final:
6315276479Sdim  case OMPC_num_threads:
6316276479Sdim  case OMPC_safelen:
6317296417Sdim  case OMPC_simdlen:
6318276479Sdim  case OMPC_collapse:
6319276479Sdim  case OMPC_schedule:
6320276479Sdim  case OMPC_private:
6321276479Sdim  case OMPC_firstprivate:
6322276479Sdim  case OMPC_lastprivate:
6323276479Sdim  case OMPC_shared:
6324276479Sdim  case OMPC_reduction:
6325276479Sdim  case OMPC_linear:
6326276479Sdim  case OMPC_aligned:
6327276479Sdim  case OMPC_copyin:
6328276479Sdim  case OMPC_copyprivate:
6329276479Sdim  case OMPC_default:
6330276479Sdim  case OMPC_proc_bind:
6331276479Sdim  case OMPC_threadprivate:
6332276479Sdim  case OMPC_flush:
6333288943Sdim  case OMPC_depend:
6334296417Sdim  case OMPC_device:
6335296417Sdim  case OMPC_map:
6336296417Sdim  case OMPC_num_teams:
6337296417Sdim  case OMPC_thread_limit:
6338296417Sdim  case OMPC_priority:
6339296417Sdim  case OMPC_grainsize:
6340296417Sdim  case OMPC_num_tasks:
6341296417Sdim  case OMPC_hint:
6342276479Sdim  case OMPC_unknown:
6343276479Sdim    llvm_unreachable("Clause is not allowed.");
6344276479Sdim  }
6345276479Sdim  return Res;
6346276479Sdim}
6347276479Sdim
6348276479SdimOMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
6349276479Sdim                                         SourceLocation EndLoc) {
6350288943Sdim  DSAStack->setNowaitRegion();
6351276479Sdim  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
6352276479Sdim}
6353276479Sdim
6354276479SdimOMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
6355276479Sdim                                         SourceLocation EndLoc) {
6356276479Sdim  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
6357276479Sdim}
6358276479Sdim
6359276479SdimOMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
6360276479Sdim                                            SourceLocation EndLoc) {
6361276479Sdim  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
6362276479Sdim}
6363276479Sdim
6364280031SdimOMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
6365280031Sdim                                       SourceLocation EndLoc) {
6366280031Sdim  return new (Context) OMPReadClause(StartLoc, EndLoc);
6367280031Sdim}
6368280031Sdim
6369280031SdimOMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
6370280031Sdim                                        SourceLocation EndLoc) {
6371280031Sdim  return new (Context) OMPWriteClause(StartLoc, EndLoc);
6372280031Sdim}
6373280031Sdim
6374280031SdimOMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
6375280031Sdim                                         SourceLocation EndLoc) {
6376280031Sdim  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
6377280031Sdim}
6378280031Sdim
6379280031SdimOMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
6380280031Sdim                                          SourceLocation EndLoc) {
6381280031Sdim  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
6382280031Sdim}
6383280031Sdim
6384280031SdimOMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
6385280031Sdim                                         SourceLocation EndLoc) {
6386280031Sdim  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
6387280031Sdim}
6388280031Sdim
6389296417SdimOMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
6390296417Sdim                                          SourceLocation EndLoc) {
6391296417Sdim  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
6392296417Sdim}
6393296417Sdim
6394296417SdimOMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
6395296417Sdim                                       SourceLocation EndLoc) {
6396296417Sdim  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
6397296417Sdim}
6398296417Sdim
6399296417SdimOMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
6400296417Sdim                                          SourceLocation EndLoc) {
6401296417Sdim  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
6402296417Sdim}
6403296417Sdim
6404276479SdimOMPClause *Sema::ActOnOpenMPVarListClause(
6405276479Sdim    OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
6406276479Sdim    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
6407276479Sdim    SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
6408288943Sdim    const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
6409296417Sdim    OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
6410296417Sdim    OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc) {
6411276479Sdim  OMPClause *Res = nullptr;
6412261991Sdim  switch (Kind) {
6413261991Sdim  case OMPC_private:
6414261991Sdim    Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
6415261991Sdim    break;
6416261991Sdim  case OMPC_firstprivate:
6417261991Sdim    Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
6418261991Sdim    break;
6419276479Sdim  case OMPC_lastprivate:
6420276479Sdim    Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
6421276479Sdim    break;
6422261991Sdim  case OMPC_shared:
6423261991Sdim    Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
6424261991Sdim    break;
6425276479Sdim  case OMPC_reduction:
6426276479Sdim    Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
6427276479Sdim                                     EndLoc, ReductionIdScopeSpec, ReductionId);
6428276479Sdim    break;
6429276479Sdim  case OMPC_linear:
6430276479Sdim    Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
6431296417Sdim                                  LinKind, DepLinMapLoc, ColonLoc, EndLoc);
6432276479Sdim    break;
6433276479Sdim  case OMPC_aligned:
6434276479Sdim    Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
6435276479Sdim                                   ColonLoc, EndLoc);
6436276479Sdim    break;
6437276479Sdim  case OMPC_copyin:
6438276479Sdim    Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
6439276479Sdim    break;
6440276479Sdim  case OMPC_copyprivate:
6441276479Sdim    Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
6442276479Sdim    break;
6443276479Sdim  case OMPC_flush:
6444276479Sdim    Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
6445276479Sdim    break;
6446288943Sdim  case OMPC_depend:
6447296417Sdim    Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
6448296417Sdim                                  StartLoc, LParenLoc, EndLoc);
6449288943Sdim    break;
6450296417Sdim  case OMPC_map:
6451296417Sdim    Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, DepLinMapLoc, ColonLoc,
6452296417Sdim                               VarList, StartLoc, LParenLoc, EndLoc);
6453296417Sdim    break;
6454276479Sdim  case OMPC_if:
6455276479Sdim  case OMPC_final:
6456276479Sdim  case OMPC_num_threads:
6457276479Sdim  case OMPC_safelen:
6458296417Sdim  case OMPC_simdlen:
6459276479Sdim  case OMPC_collapse:
6460261991Sdim  case OMPC_default:
6461276479Sdim  case OMPC_proc_bind:
6462276479Sdim  case OMPC_schedule:
6463276479Sdim  case OMPC_ordered:
6464276479Sdim  case OMPC_nowait:
6465276479Sdim  case OMPC_untied:
6466276479Sdim  case OMPC_mergeable:
6467261991Sdim  case OMPC_threadprivate:
6468280031Sdim  case OMPC_read:
6469280031Sdim  case OMPC_write:
6470280031Sdim  case OMPC_update:
6471280031Sdim  case OMPC_capture:
6472280031Sdim  case OMPC_seq_cst:
6473296417Sdim  case OMPC_device:
6474296417Sdim  case OMPC_threads:
6475296417Sdim  case OMPC_simd:
6476296417Sdim  case OMPC_num_teams:
6477296417Sdim  case OMPC_thread_limit:
6478296417Sdim  case OMPC_priority:
6479296417Sdim  case OMPC_grainsize:
6480296417Sdim  case OMPC_nogroup:
6481296417Sdim  case OMPC_num_tasks:
6482296417Sdim  case OMPC_hint:
6483261991Sdim  case OMPC_unknown:
6484261991Sdim    llvm_unreachable("Clause is not allowed.");
6485261991Sdim  }
6486261991Sdim  return Res;
6487261991Sdim}
6488261991Sdim
6489261991SdimOMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
6490261991Sdim                                          SourceLocation StartLoc,
6491261991Sdim                                          SourceLocation LParenLoc,
6492261991Sdim                                          SourceLocation EndLoc) {
6493261991Sdim  SmallVector<Expr *, 8> Vars;
6494280031Sdim  SmallVector<Expr *, 8> PrivateCopies;
6495276479Sdim  for (auto &RefExpr : VarList) {
6496276479Sdim    assert(RefExpr && "NULL expr in OpenMP private clause.");
6497276479Sdim    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6498261991Sdim      // It will be analyzed later.
6499276479Sdim      Vars.push_back(RefExpr);
6500280031Sdim      PrivateCopies.push_back(nullptr);
6501261991Sdim      continue;
6502261991Sdim    }
6503261991Sdim
6504276479Sdim    SourceLocation ELoc = RefExpr->getExprLoc();
6505261991Sdim    // OpenMP [2.1, C/C++]
6506261991Sdim    //  A list item is a variable name.
6507261991Sdim    // OpenMP  [2.9.3.3, Restrictions, p.1]
6508261991Sdim    //  A variable that is part of another variable (as an array or
6509261991Sdim    //  structure element) cannot appear in a private clause.
6510276479Sdim    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
6511261991Sdim    if (!DE || !isa<VarDecl>(DE->getDecl())) {
6512276479Sdim      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6513261991Sdim      continue;
6514261991Sdim    }
6515261991Sdim    Decl *D = DE->getDecl();
6516261991Sdim    VarDecl *VD = cast<VarDecl>(D);
6517261991Sdim
6518261991Sdim    QualType Type = VD->getType();
6519261991Sdim    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6520261991Sdim      // It will be analyzed later.
6521261991Sdim      Vars.push_back(DE);
6522280031Sdim      PrivateCopies.push_back(nullptr);
6523261991Sdim      continue;
6524261991Sdim    }
6525261991Sdim
6526261991Sdim    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
6527261991Sdim    //  A variable that appears in a private clause must not have an incomplete
6528261991Sdim    //  type or a reference type.
6529261991Sdim    if (RequireCompleteType(ELoc, Type,
6530261991Sdim                            diag::err_omp_private_incomplete_type)) {
6531261991Sdim      continue;
6532261991Sdim    }
6533296417Sdim    Type = Type.getNonReferenceType();
6534261991Sdim
6535261991Sdim    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
6536261991Sdim    // in a Construct]
6537261991Sdim    //  Variables with the predetermined data-sharing attributes may not be
6538261991Sdim    //  listed in data-sharing attributes clauses, except for the cases
6539261991Sdim    //  listed below. For these exceptions only, listing a predetermined
6540261991Sdim    //  variable in a data-sharing attribute clause is allowed and overrides
6541261991Sdim    //  the variable's predetermined data-sharing attributes.
6542276479Sdim    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
6543261991Sdim    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
6544276479Sdim      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
6545276479Sdim                                          << getOpenMPClauseName(OMPC_private);
6546276479Sdim      ReportOriginalDSA(*this, DSAStack, VD, DVar);
6547261991Sdim      continue;
6548261991Sdim    }
6549261991Sdim
6550288943Sdim    // Variably modified types are not supported for tasks.
6551288943Sdim    if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
6552288943Sdim        DSAStack->getCurrentDirective() == OMPD_task) {
6553288943Sdim      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
6554288943Sdim          << getOpenMPClauseName(OMPC_private) << Type
6555288943Sdim          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
6556288943Sdim      bool IsDecl =
6557288943Sdim          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
6558288943Sdim      Diag(VD->getLocation(),
6559288943Sdim           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6560288943Sdim          << VD;
6561288943Sdim      continue;
6562288943Sdim    }
6563288943Sdim
6564288943Sdim    // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
6565288943Sdim    //  A variable of class type (or array thereof) that appears in a private
6566288943Sdim    //  clause requires an accessible, unambiguous default constructor for the
6567288943Sdim    //  class type.
6568280031Sdim    // Generate helper private variable and initialize it with the default
6569280031Sdim    // value. The address of the original variable is replaced by the address of
6570280031Sdim    // the new private variable in CodeGen. This new variable is not added to
6571280031Sdim    // IdResolver, so the code in the OpenMP region uses original variable for
6572280031Sdim    // proper diagnostics.
6573288943Sdim    Type = Type.getUnqualifiedType();
6574296417Sdim    auto VDPrivate = buildVarDecl(*this, DE->getExprLoc(), Type, VD->getName(),
6575296417Sdim                                  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
6576288943Sdim    ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
6577280031Sdim    if (VDPrivate->isInvalidDecl())
6578280031Sdim      continue;
6579288943Sdim    auto VDPrivateRefExpr = buildDeclRefExpr(
6580288943Sdim        *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc());
6581280031Sdim
6582261991Sdim    DSAStack->addDSA(VD, DE, OMPC_private);
6583261991Sdim    Vars.push_back(DE);
6584280031Sdim    PrivateCopies.push_back(VDPrivateRefExpr);
6585261991Sdim  }
6586261991Sdim
6587276479Sdim  if (Vars.empty())
6588276479Sdim    return nullptr;
6589261991Sdim
6590280031Sdim  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
6591280031Sdim                                  PrivateCopies);
6592261991Sdim}
6593261991Sdim
6594280031Sdimnamespace {
6595280031Sdimclass DiagsUninitializedSeveretyRAII {
6596280031Sdimprivate:
6597280031Sdim  DiagnosticsEngine &Diags;
6598280031Sdim  SourceLocation SavedLoc;
6599280031Sdim  bool IsIgnored;
6600280031Sdim
6601280031Sdimpublic:
6602280031Sdim  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
6603280031Sdim                                 bool IsIgnored)
6604280031Sdim      : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
6605280031Sdim    if (!IsIgnored) {
6606280031Sdim      Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
6607280031Sdim                        /*Map*/ diag::Severity::Ignored, Loc);
6608280031Sdim    }
6609280031Sdim  }
6610280031Sdim  ~DiagsUninitializedSeveretyRAII() {
6611280031Sdim    if (!IsIgnored)
6612280031Sdim      Diags.popMappings(SavedLoc);
6613280031Sdim  }
6614280031Sdim};
6615280031Sdim}
6616280031Sdim
6617261991SdimOMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
6618261991Sdim                                               SourceLocation StartLoc,
6619261991Sdim                                               SourceLocation LParenLoc,
6620261991Sdim                                               SourceLocation EndLoc) {
6621261991Sdim  SmallVector<Expr *, 8> Vars;
6622280031Sdim  SmallVector<Expr *, 8> PrivateCopies;
6623280031Sdim  SmallVector<Expr *, 8> Inits;
6624276479Sdim  bool IsImplicitClause =
6625276479Sdim      StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
6626276479Sdim  auto ImplicitClauseLoc = DSAStack->getConstructLoc();
6627276479Sdim
6628276479Sdim  for (auto &RefExpr : VarList) {
6629276479Sdim    assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
6630276479Sdim    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6631261991Sdim      // It will be analyzed later.
6632276479Sdim      Vars.push_back(RefExpr);
6633280031Sdim      PrivateCopies.push_back(nullptr);
6634280031Sdim      Inits.push_back(nullptr);
6635261991Sdim      continue;
6636261991Sdim    }
6637261991Sdim
6638280031Sdim    SourceLocation ELoc =
6639280031Sdim        IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc();
6640261991Sdim    // OpenMP [2.1, C/C++]
6641261991Sdim    //  A list item is a variable name.
6642261991Sdim    // OpenMP  [2.9.3.3, Restrictions, p.1]
6643261991Sdim    //  A variable that is part of another variable (as an array or
6644261991Sdim    //  structure element) cannot appear in a private clause.
6645276479Sdim    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
6646261991Sdim    if (!DE || !isa<VarDecl>(DE->getDecl())) {
6647276479Sdim      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6648261991Sdim      continue;
6649261991Sdim    }
6650261991Sdim    Decl *D = DE->getDecl();
6651261991Sdim    VarDecl *VD = cast<VarDecl>(D);
6652261991Sdim
6653261991Sdim    QualType Type = VD->getType();
6654261991Sdim    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6655261991Sdim      // It will be analyzed later.
6656261991Sdim      Vars.push_back(DE);
6657280031Sdim      PrivateCopies.push_back(nullptr);
6658280031Sdim      Inits.push_back(nullptr);
6659261991Sdim      continue;
6660261991Sdim    }
6661261991Sdim
6662261991Sdim    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
6663261991Sdim    //  A variable that appears in a private clause must not have an incomplete
6664261991Sdim    //  type or a reference type.
6665261991Sdim    if (RequireCompleteType(ELoc, Type,
6666261991Sdim                            diag::err_omp_firstprivate_incomplete_type)) {
6667261991Sdim      continue;
6668261991Sdim    }
6669296417Sdim    Type = Type.getNonReferenceType();
6670261991Sdim
6671261991Sdim    // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
6672261991Sdim    //  A variable of class type (or array thereof) that appears in a private
6673276479Sdim    //  clause requires an accessible, unambiguous copy constructor for the
6674261991Sdim    //  class type.
6675288943Sdim    auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
6676261991Sdim
6677276479Sdim    // If an implicit firstprivate variable found it was checked already.
6678276479Sdim    if (!IsImplicitClause) {
6679276479Sdim      DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
6680288943Sdim      bool IsConstant = ElemType.isConstant(Context);
6681261991Sdim      // OpenMP [2.4.13, Data-sharing Attribute Clauses]
6682261991Sdim      //  A list item that specifies a given variable may not appear in more
6683261991Sdim      // than one clause on the same directive, except that a variable may be
6684261991Sdim      //  specified in both firstprivate and lastprivate clauses.
6685261991Sdim      if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
6686276479Sdim          DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
6687261991Sdim        Diag(ELoc, diag::err_omp_wrong_dsa)
6688276479Sdim            << getOpenMPClauseName(DVar.CKind)
6689276479Sdim            << getOpenMPClauseName(OMPC_firstprivate);
6690276479Sdim        ReportOriginalDSA(*this, DSAStack, VD, DVar);
6691261991Sdim        continue;
6692261991Sdim      }
6693261991Sdim
6694261991Sdim      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
6695261991Sdim      // in a Construct]
6696261991Sdim      //  Variables with the predetermined data-sharing attributes may not be
6697261991Sdim      //  listed in data-sharing attributes clauses, except for the cases
6698261991Sdim      //  listed below. For these exceptions only, listing a predetermined
6699261991Sdim      //  variable in a data-sharing attribute clause is allowed and overrides
6700261991Sdim      //  the variable's predetermined data-sharing attributes.
6701261991Sdim      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
6702261991Sdim      // in a Construct, C/C++, p.2]
6703261991Sdim      //  Variables with const-qualified type having no mutable member may be
6704261991Sdim      //  listed in a firstprivate clause, even if they are static data members.
6705261991Sdim      if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr &&
6706261991Sdim          DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
6707261991Sdim        Diag(ELoc, diag::err_omp_wrong_dsa)
6708276479Sdim            << getOpenMPClauseName(DVar.CKind)
6709276479Sdim            << getOpenMPClauseName(OMPC_firstprivate);
6710276479Sdim        ReportOriginalDSA(*this, DSAStack, VD, DVar);
6711261991Sdim        continue;
6712261991Sdim      }
6713261991Sdim
6714276479Sdim      OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
6715261991Sdim      // OpenMP [2.9.3.4, Restrictions, p.2]
6716261991Sdim      //  A list item that is private within a parallel region must not appear
6717261991Sdim      //  in a firstprivate clause on a worksharing construct if any of the
6718261991Sdim      //  worksharing regions arising from the worksharing construct ever bind
6719261991Sdim      //  to any of the parallel regions arising from the parallel construct.
6720276479Sdim      if (isOpenMPWorksharingDirective(CurrDir) &&
6721276479Sdim          !isOpenMPParallelDirective(CurrDir)) {
6722276479Sdim        DVar = DSAStack->getImplicitDSA(VD, true);
6723276479Sdim        if (DVar.CKind != OMPC_shared &&
6724276479Sdim            (isOpenMPParallelDirective(DVar.DKind) ||
6725276479Sdim             DVar.DKind == OMPD_unknown)) {
6726276479Sdim          Diag(ELoc, diag::err_omp_required_access)
6727276479Sdim              << getOpenMPClauseName(OMPC_firstprivate)
6728276479Sdim              << getOpenMPClauseName(OMPC_shared);
6729276479Sdim          ReportOriginalDSA(*this, DSAStack, VD, DVar);
6730276479Sdim          continue;
6731276479Sdim        }
6732276479Sdim      }
6733261991Sdim      // OpenMP [2.9.3.4, Restrictions, p.3]
6734261991Sdim      //  A list item that appears in a reduction clause of a parallel construct
6735261991Sdim      //  must not appear in a firstprivate clause on a worksharing or task
6736261991Sdim      //  construct if any of the worksharing or task regions arising from the
6737261991Sdim      //  worksharing or task construct ever bind to any of the parallel regions
6738261991Sdim      //  arising from the parallel construct.
6739261991Sdim      // OpenMP [2.9.3.4, Restrictions, p.4]
6740261991Sdim      //  A list item that appears in a reduction clause in worksharing
6741261991Sdim      //  construct must not appear in a firstprivate clause in a task construct
6742261991Sdim      //  encountered during execution of any of the worksharing regions arising
6743261991Sdim      //  from the worksharing construct.
6744276479Sdim      if (CurrDir == OMPD_task) {
6745276479Sdim        DVar =
6746276479Sdim            DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
6747276479Sdim                                      [](OpenMPDirectiveKind K) -> bool {
6748276479Sdim                                        return isOpenMPParallelDirective(K) ||
6749276479Sdim                                               isOpenMPWorksharingDirective(K);
6750276479Sdim                                      },
6751276479Sdim                                      false);
6752276479Sdim        if (DVar.CKind == OMPC_reduction &&
6753276479Sdim            (isOpenMPParallelDirective(DVar.DKind) ||
6754276479Sdim             isOpenMPWorksharingDirective(DVar.DKind))) {
6755276479Sdim          Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
6756276479Sdim              << getOpenMPDirectiveName(DVar.DKind);
6757276479Sdim          ReportOriginalDSA(*this, DSAStack, VD, DVar);
6758276479Sdim          continue;
6759276479Sdim        }
6760276479Sdim      }
6761296417Sdim
6762296417Sdim      // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
6763296417Sdim      // A list item that is private within a teams region must not appear in a
6764296417Sdim      // firstprivate clause on a distribute construct if any of the distribute
6765296417Sdim      // regions arising from the distribute construct ever bind to any of the
6766296417Sdim      // teams regions arising from the teams construct.
6767296417Sdim      // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
6768296417Sdim      // A list item that appears in a reduction clause of a teams construct
6769296417Sdim      // must not appear in a firstprivate clause on a distribute construct if
6770296417Sdim      // any of the distribute regions arising from the distribute construct
6771296417Sdim      // ever bind to any of the teams regions arising from the teams construct.
6772296417Sdim      // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
6773296417Sdim      // A list item may appear in a firstprivate or lastprivate clause but not
6774296417Sdim      // both.
6775296417Sdim      if (CurrDir == OMPD_distribute) {
6776296417Sdim        DVar = DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_private),
6777296417Sdim                                         [](OpenMPDirectiveKind K) -> bool {
6778296417Sdim                                           return isOpenMPTeamsDirective(K);
6779296417Sdim                                         },
6780296417Sdim                                         false);
6781296417Sdim        if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) {
6782296417Sdim          Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams);
6783296417Sdim          ReportOriginalDSA(*this, DSAStack, VD, DVar);
6784296417Sdim          continue;
6785296417Sdim        }
6786296417Sdim        DVar = DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
6787296417Sdim                                         [](OpenMPDirectiveKind K) -> bool {
6788296417Sdim                                           return isOpenMPTeamsDirective(K);
6789296417Sdim                                         },
6790296417Sdim                                         false);
6791296417Sdim        if (DVar.CKind == OMPC_reduction &&
6792296417Sdim            isOpenMPTeamsDirective(DVar.DKind)) {
6793296417Sdim          Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction);
6794296417Sdim          ReportOriginalDSA(*this, DSAStack, VD, DVar);
6795296417Sdim          continue;
6796296417Sdim        }
6797296417Sdim        DVar = DSAStack->getTopDSA(VD, false);
6798296417Sdim        if (DVar.CKind == OMPC_lastprivate) {
6799296417Sdim          Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
6800296417Sdim          ReportOriginalDSA(*this, DSAStack, VD, DVar);
6801296417Sdim          continue;
6802296417Sdim        }
6803296417Sdim      }
6804261991Sdim    }
6805261991Sdim
6806288943Sdim    // Variably modified types are not supported for tasks.
6807288943Sdim    if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
6808288943Sdim        DSAStack->getCurrentDirective() == OMPD_task) {
6809288943Sdim      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
6810288943Sdim          << getOpenMPClauseName(OMPC_firstprivate) << Type
6811288943Sdim          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
6812288943Sdim      bool IsDecl =
6813288943Sdim          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
6814288943Sdim      Diag(VD->getLocation(),
6815288943Sdim           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6816288943Sdim          << VD;
6817288943Sdim      continue;
6818288943Sdim    }
6819288943Sdim
6820280031Sdim    Type = Type.getUnqualifiedType();
6821296417Sdim    auto VDPrivate = buildVarDecl(*this, ELoc, Type, VD->getName(),
6822296417Sdim                                  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
6823280031Sdim    // Generate helper private variable and initialize it with the value of the
6824280031Sdim    // original variable. The address of the original variable is replaced by
6825280031Sdim    // the address of the new private variable in the CodeGen. This new variable
6826280031Sdim    // is not added to IdResolver, so the code in the OpenMP region uses
6827280031Sdim    // original variable for proper diagnostics and variable capturing.
6828280031Sdim    Expr *VDInitRefExpr = nullptr;
6829280031Sdim    // For arrays generate initializer for single element and replace it by the
6830280031Sdim    // original array element in CodeGen.
6831288943Sdim    if (Type->isArrayType()) {
6832288943Sdim      auto VDInit =
6833288943Sdim          buildVarDecl(*this, DE->getExprLoc(), ElemType, VD->getName());
6834288943Sdim      VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
6835280031Sdim      auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
6836288943Sdim      ElemType = ElemType.getUnqualifiedType();
6837288943Sdim      auto *VDInitTemp = buildVarDecl(*this, DE->getLocStart(), ElemType,
6838288943Sdim                                      ".firstprivate.temp");
6839288943Sdim      InitializedEntity Entity =
6840288943Sdim          InitializedEntity::InitializeVariable(VDInitTemp);
6841280031Sdim      InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
6842280031Sdim
6843280031Sdim      InitializationSequence InitSeq(*this, Entity, Kind, Init);
6844280031Sdim      ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
6845280031Sdim      if (Result.isInvalid())
6846280031Sdim        VDPrivate->setInvalidDecl();
6847280031Sdim      else
6848280031Sdim        VDPrivate->setInit(Result.getAs<Expr>());
6849296417Sdim      // Remove temp variable declaration.
6850296417Sdim      Context.Deallocate(VDInitTemp);
6851280031Sdim    } else {
6852288943Sdim      auto *VDInit =
6853288943Sdim          buildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp");
6854288943Sdim      VDInitRefExpr =
6855288943Sdim          buildDeclRefExpr(*this, VDInit, DE->getType(), DE->getExprLoc());
6856288943Sdim      AddInitializerToDecl(VDPrivate,
6857288943Sdim                           DefaultLvalueConversion(VDInitRefExpr).get(),
6858288943Sdim                           /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
6859280031Sdim    }
6860280031Sdim    if (VDPrivate->isInvalidDecl()) {
6861280031Sdim      if (IsImplicitClause) {
6862280031Sdim        Diag(DE->getExprLoc(),
6863280031Sdim             diag::note_omp_task_predetermined_firstprivate_here);
6864280031Sdim      }
6865280031Sdim      continue;
6866280031Sdim    }
6867280031Sdim    CurContext->addDecl(VDPrivate);
6868288943Sdim    auto VDPrivateRefExpr = buildDeclRefExpr(
6869288943Sdim        *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc());
6870261991Sdim    DSAStack->addDSA(VD, DE, OMPC_firstprivate);
6871261991Sdim    Vars.push_back(DE);
6872280031Sdim    PrivateCopies.push_back(VDPrivateRefExpr);
6873280031Sdim    Inits.push_back(VDInitRefExpr);
6874261991Sdim  }
6875261991Sdim
6876276479Sdim  if (Vars.empty())
6877276479Sdim    return nullptr;
6878261991Sdim
6879261991Sdim  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
6880280031Sdim                                       Vars, PrivateCopies, Inits);
6881261991Sdim}
6882261991Sdim
6883276479SdimOMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
6884276479Sdim                                              SourceLocation StartLoc,
6885276479Sdim                                              SourceLocation LParenLoc,
6886276479Sdim                                              SourceLocation EndLoc) {
6887276479Sdim  SmallVector<Expr *, 8> Vars;
6888288943Sdim  SmallVector<Expr *, 8> SrcExprs;
6889288943Sdim  SmallVector<Expr *, 8> DstExprs;
6890288943Sdim  SmallVector<Expr *, 8> AssignmentOps;
6891276479Sdim  for (auto &RefExpr : VarList) {
6892276479Sdim    assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
6893276479Sdim    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6894276479Sdim      // It will be analyzed later.
6895276479Sdim      Vars.push_back(RefExpr);
6896288943Sdim      SrcExprs.push_back(nullptr);
6897288943Sdim      DstExprs.push_back(nullptr);
6898288943Sdim      AssignmentOps.push_back(nullptr);
6899276479Sdim      continue;
6900276479Sdim    }
6901276479Sdim
6902276479Sdim    SourceLocation ELoc = RefExpr->getExprLoc();
6903276479Sdim    // OpenMP [2.1, C/C++]
6904276479Sdim    //  A list item is a variable name.
6905276479Sdim    // OpenMP  [2.14.3.5, Restrictions, p.1]
6906276479Sdim    //  A variable that is part of another variable (as an array or structure
6907276479Sdim    //  element) cannot appear in a lastprivate clause.
6908276479Sdim    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
6909276479Sdim    if (!DE || !isa<VarDecl>(DE->getDecl())) {
6910276479Sdim      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6911276479Sdim      continue;
6912276479Sdim    }
6913276479Sdim    Decl *D = DE->getDecl();
6914276479Sdim    VarDecl *VD = cast<VarDecl>(D);
6915276479Sdim
6916276479Sdim    QualType Type = VD->getType();
6917276479Sdim    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6918276479Sdim      // It will be analyzed later.
6919276479Sdim      Vars.push_back(DE);
6920288943Sdim      SrcExprs.push_back(nullptr);
6921288943Sdim      DstExprs.push_back(nullptr);
6922288943Sdim      AssignmentOps.push_back(nullptr);
6923276479Sdim      continue;
6924276479Sdim    }
6925276479Sdim
6926276479Sdim    // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
6927276479Sdim    //  A variable that appears in a lastprivate clause must not have an
6928276479Sdim    //  incomplete type or a reference type.
6929276479Sdim    if (RequireCompleteType(ELoc, Type,
6930276479Sdim                            diag::err_omp_lastprivate_incomplete_type)) {
6931276479Sdim      continue;
6932276479Sdim    }
6933296417Sdim    Type = Type.getNonReferenceType();
6934276479Sdim
6935276479Sdim    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
6936276479Sdim    // in a Construct]
6937276479Sdim    //  Variables with the predetermined data-sharing attributes may not be
6938276479Sdim    //  listed in data-sharing attributes clauses, except for the cases
6939276479Sdim    //  listed below.
6940276479Sdim    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
6941276479Sdim    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
6942276479Sdim        DVar.CKind != OMPC_firstprivate &&
6943276479Sdim        (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
6944276479Sdim      Diag(ELoc, diag::err_omp_wrong_dsa)
6945276479Sdim          << getOpenMPClauseName(DVar.CKind)
6946276479Sdim          << getOpenMPClauseName(OMPC_lastprivate);
6947276479Sdim      ReportOriginalDSA(*this, DSAStack, VD, DVar);
6948276479Sdim      continue;
6949276479Sdim    }
6950276479Sdim
6951276479Sdim    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
6952276479Sdim    // OpenMP [2.14.3.5, Restrictions, p.2]
6953276479Sdim    // A list item that is private within a parallel region, or that appears in
6954276479Sdim    // the reduction clause of a parallel construct, must not appear in a
6955276479Sdim    // lastprivate clause on a worksharing construct if any of the corresponding
6956276479Sdim    // worksharing regions ever binds to any of the corresponding parallel
6957276479Sdim    // regions.
6958288943Sdim    DSAStackTy::DSAVarData TopDVar = DVar;
6959276479Sdim    if (isOpenMPWorksharingDirective(CurrDir) &&
6960276479Sdim        !isOpenMPParallelDirective(CurrDir)) {
6961276479Sdim      DVar = DSAStack->getImplicitDSA(VD, true);
6962276479Sdim      if (DVar.CKind != OMPC_shared) {
6963276479Sdim        Diag(ELoc, diag::err_omp_required_access)
6964276479Sdim            << getOpenMPClauseName(OMPC_lastprivate)
6965276479Sdim            << getOpenMPClauseName(OMPC_shared);
6966276479Sdim        ReportOriginalDSA(*this, DSAStack, VD, DVar);
6967276479Sdim        continue;
6968276479Sdim      }
6969276479Sdim    }
6970276479Sdim    // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
6971276479Sdim    //  A variable of class type (or array thereof) that appears in a
6972276479Sdim    //  lastprivate clause requires an accessible, unambiguous default
6973276479Sdim    //  constructor for the class type, unless the list item is also specified
6974276479Sdim    //  in a firstprivate clause.
6975276479Sdim    //  A variable of class type (or array thereof) that appears in a
6976276479Sdim    //  lastprivate clause requires an accessible, unambiguous copy assignment
6977276479Sdim    //  operator for the class type.
6978288943Sdim    Type = Context.getBaseElementType(Type).getNonReferenceType();
6979288943Sdim    auto *SrcVD = buildVarDecl(*this, DE->getLocStart(),
6980296417Sdim                               Type.getUnqualifiedType(), ".lastprivate.src",
6981296417Sdim                               VD->hasAttrs() ? &VD->getAttrs() : nullptr);
6982288943Sdim    auto *PseudoSrcExpr = buildDeclRefExpr(
6983288943Sdim        *this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc());
6984288943Sdim    auto *DstVD =
6985296417Sdim        buildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst",
6986296417Sdim                     VD->hasAttrs() ? &VD->getAttrs() : nullptr);
6987288943Sdim    auto *PseudoDstExpr =
6988288943Sdim        buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
6989288943Sdim    // For arrays generate assignment operation for single element and replace
6990288943Sdim    // it by the original array element in CodeGen.
6991288943Sdim    auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
6992288943Sdim                                   PseudoDstExpr, PseudoSrcExpr);
6993288943Sdim    if (AssignmentOp.isInvalid())
6994288943Sdim      continue;
6995288943Sdim    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
6996288943Sdim                                       /*DiscardedValue=*/true);
6997288943Sdim    if (AssignmentOp.isInvalid())
6998288943Sdim      continue;
6999276479Sdim
7000296417Sdim    // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
7001296417Sdim    // A list item may appear in a firstprivate or lastprivate clause but not
7002296417Sdim    // both.
7003296417Sdim    if (CurrDir == OMPD_distribute) {
7004296417Sdim      DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
7005296417Sdim      if (DVar.CKind == OMPC_firstprivate) {
7006296417Sdim        Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
7007296417Sdim        ReportOriginalDSA(*this, DSAStack, VD, DVar);
7008296417Sdim        continue;
7009296417Sdim      }
7010296417Sdim    }
7011296417Sdim
7012288943Sdim    if (TopDVar.CKind != OMPC_firstprivate)
7013276479Sdim      DSAStack->addDSA(VD, DE, OMPC_lastprivate);
7014276479Sdim    Vars.push_back(DE);
7015288943Sdim    SrcExprs.push_back(PseudoSrcExpr);
7016288943Sdim    DstExprs.push_back(PseudoDstExpr);
7017288943Sdim    AssignmentOps.push_back(AssignmentOp.get());
7018276479Sdim  }
7019276479Sdim
7020276479Sdim  if (Vars.empty())
7021276479Sdim    return nullptr;
7022276479Sdim
7023276479Sdim  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
7024288943Sdim                                      Vars, SrcExprs, DstExprs, AssignmentOps);
7025276479Sdim}
7026276479Sdim
7027261991SdimOMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
7028261991Sdim                                         SourceLocation StartLoc,
7029261991Sdim                                         SourceLocation LParenLoc,
7030261991Sdim                                         SourceLocation EndLoc) {
7031261991Sdim  SmallVector<Expr *, 8> Vars;
7032276479Sdim  for (auto &RefExpr : VarList) {
7033276479Sdim    assert(RefExpr && "NULL expr in OpenMP shared clause.");
7034276479Sdim    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7035261991Sdim      // It will be analyzed later.
7036276479Sdim      Vars.push_back(RefExpr);
7037261991Sdim      continue;
7038261991Sdim    }
7039261991Sdim
7040276479Sdim    SourceLocation ELoc = RefExpr->getExprLoc();
7041261991Sdim    // OpenMP [2.1, C/C++]
7042261991Sdim    //  A list item is a variable name.
7043276479Sdim    // OpenMP  [2.14.3.2, Restrictions, p.1]
7044276479Sdim    //  A variable that is part of another variable (as an array or structure
7045276479Sdim    //  element) cannot appear in a shared unless it is a static data member
7046276479Sdim    //  of a C++ class.
7047276479Sdim    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
7048261991Sdim    if (!DE || !isa<VarDecl>(DE->getDecl())) {
7049276479Sdim      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7050261991Sdim      continue;
7051261991Sdim    }
7052261991Sdim    Decl *D = DE->getDecl();
7053261991Sdim    VarDecl *VD = cast<VarDecl>(D);
7054261991Sdim
7055261991Sdim    QualType Type = VD->getType();
7056261991Sdim    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
7057261991Sdim      // It will be analyzed later.
7058261991Sdim      Vars.push_back(DE);
7059261991Sdim      continue;
7060261991Sdim    }
7061261991Sdim
7062261991Sdim    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
7063261991Sdim    // in a Construct]
7064261991Sdim    //  Variables with the predetermined data-sharing attributes may not be
7065261991Sdim    //  listed in data-sharing attributes clauses, except for the cases
7066261991Sdim    //  listed below. For these exceptions only, listing a predetermined
7067261991Sdim    //  variable in a data-sharing attribute clause is allowed and overrides
7068261991Sdim    //  the variable's predetermined data-sharing attributes.
7069276479Sdim    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
7070276479Sdim    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
7071276479Sdim        DVar.RefExpr) {
7072276479Sdim      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
7073276479Sdim                                          << getOpenMPClauseName(OMPC_shared);
7074276479Sdim      ReportOriginalDSA(*this, DSAStack, VD, DVar);
7075261991Sdim      continue;
7076261991Sdim    }
7077261991Sdim
7078261991Sdim    DSAStack->addDSA(VD, DE, OMPC_shared);
7079261991Sdim    Vars.push_back(DE);
7080261991Sdim  }
7081261991Sdim
7082276479Sdim  if (Vars.empty())
7083276479Sdim    return nullptr;
7084261991Sdim
7085261991Sdim  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
7086261991Sdim}
7087261991Sdim
7088276479Sdimnamespace {
7089276479Sdimclass DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
7090276479Sdim  DSAStackTy *Stack;
7091276479Sdim
7092276479Sdimpublic:
7093276479Sdim  bool VisitDeclRefExpr(DeclRefExpr *E) {
7094276479Sdim    if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
7095276479Sdim      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false);
7096276479Sdim      if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
7097276479Sdim        return false;
7098276479Sdim      if (DVar.CKind != OMPC_unknown)
7099276479Sdim        return true;
7100276479Sdim      DSAStackTy::DSAVarData DVarPrivate =
7101276479Sdim          Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false);
7102276479Sdim      if (DVarPrivate.CKind != OMPC_unknown)
7103276479Sdim        return true;
7104276479Sdim      return false;
7105276479Sdim    }
7106276479Sdim    return false;
7107276479Sdim  }
7108276479Sdim  bool VisitStmt(Stmt *S) {
7109276479Sdim    for (auto Child : S->children()) {
7110276479Sdim      if (Child && Visit(Child))
7111276479Sdim        return true;
7112276479Sdim    }
7113276479Sdim    return false;
7114276479Sdim  }
7115276479Sdim  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
7116276479Sdim};
7117276479Sdim} // namespace
7118276479Sdim
7119276479SdimOMPClause *Sema::ActOnOpenMPReductionClause(
7120276479Sdim    ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
7121276479Sdim    SourceLocation ColonLoc, SourceLocation EndLoc,
7122276479Sdim    CXXScopeSpec &ReductionIdScopeSpec,
7123276479Sdim    const DeclarationNameInfo &ReductionId) {
7124276479Sdim  // TODO: Allow scope specification search when 'declare reduction' is
7125276479Sdim  // supported.
7126276479Sdim  assert(ReductionIdScopeSpec.isEmpty() &&
7127276479Sdim         "No support for scoped reduction identifiers yet.");
7128276479Sdim
7129276479Sdim  auto DN = ReductionId.getName();
7130276479Sdim  auto OOK = DN.getCXXOverloadedOperator();
7131276479Sdim  BinaryOperatorKind BOK = BO_Comma;
7132276479Sdim
7133276479Sdim  // OpenMP [2.14.3.6, reduction clause]
7134276479Sdim  // C
7135276479Sdim  // reduction-identifier is either an identifier or one of the following
7136276479Sdim  // operators: +, -, *,  &, |, ^, && and ||
7137276479Sdim  // C++
7138276479Sdim  // reduction-identifier is either an id-expression or one of the following
7139276479Sdim  // operators: +, -, *, &, |, ^, && and ||
7140276479Sdim  // FIXME: Only 'min' and 'max' identifiers are supported for now.
7141276479Sdim  switch (OOK) {
7142276479Sdim  case OO_Plus:
7143276479Sdim  case OO_Minus:
7144288943Sdim    BOK = BO_Add;
7145276479Sdim    break;
7146276479Sdim  case OO_Star:
7147288943Sdim    BOK = BO_Mul;
7148276479Sdim    break;
7149276479Sdim  case OO_Amp:
7150288943Sdim    BOK = BO_And;
7151276479Sdim    break;
7152276479Sdim  case OO_Pipe:
7153288943Sdim    BOK = BO_Or;
7154276479Sdim    break;
7155276479Sdim  case OO_Caret:
7156288943Sdim    BOK = BO_Xor;
7157276479Sdim    break;
7158276479Sdim  case OO_AmpAmp:
7159276479Sdim    BOK = BO_LAnd;
7160276479Sdim    break;
7161276479Sdim  case OO_PipePipe:
7162276479Sdim    BOK = BO_LOr;
7163276479Sdim    break;
7164288943Sdim  case OO_New:
7165288943Sdim  case OO_Delete:
7166288943Sdim  case OO_Array_New:
7167288943Sdim  case OO_Array_Delete:
7168288943Sdim  case OO_Slash:
7169288943Sdim  case OO_Percent:
7170288943Sdim  case OO_Tilde:
7171288943Sdim  case OO_Exclaim:
7172288943Sdim  case OO_Equal:
7173288943Sdim  case OO_Less:
7174288943Sdim  case OO_Greater:
7175288943Sdim  case OO_LessEqual:
7176288943Sdim  case OO_GreaterEqual:
7177288943Sdim  case OO_PlusEqual:
7178288943Sdim  case OO_MinusEqual:
7179288943Sdim  case OO_StarEqual:
7180288943Sdim  case OO_SlashEqual:
7181288943Sdim  case OO_PercentEqual:
7182288943Sdim  case OO_CaretEqual:
7183288943Sdim  case OO_AmpEqual:
7184288943Sdim  case OO_PipeEqual:
7185288943Sdim  case OO_LessLess:
7186288943Sdim  case OO_GreaterGreater:
7187288943Sdim  case OO_LessLessEqual:
7188288943Sdim  case OO_GreaterGreaterEqual:
7189288943Sdim  case OO_EqualEqual:
7190288943Sdim  case OO_ExclaimEqual:
7191288943Sdim  case OO_PlusPlus:
7192288943Sdim  case OO_MinusMinus:
7193288943Sdim  case OO_Comma:
7194288943Sdim  case OO_ArrowStar:
7195288943Sdim  case OO_Arrow:
7196288943Sdim  case OO_Call:
7197288943Sdim  case OO_Subscript:
7198288943Sdim  case OO_Conditional:
7199296417Sdim  case OO_Coawait:
7200288943Sdim  case NUM_OVERLOADED_OPERATORS:
7201288943Sdim    llvm_unreachable("Unexpected reduction identifier");
7202288943Sdim  case OO_None:
7203276479Sdim    if (auto II = DN.getAsIdentifierInfo()) {
7204276479Sdim      if (II->isStr("max"))
7205276479Sdim        BOK = BO_GT;
7206276479Sdim      else if (II->isStr("min"))
7207276479Sdim        BOK = BO_LT;
7208276479Sdim    }
7209276479Sdim    break;
7210276479Sdim  }
7211276479Sdim  SourceRange ReductionIdRange;
7212276479Sdim  if (ReductionIdScopeSpec.isValid()) {
7213276479Sdim    ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
7214276479Sdim  }
7215276479Sdim  ReductionIdRange.setEnd(ReductionId.getEndLoc());
7216276479Sdim  if (BOK == BO_Comma) {
7217276479Sdim    // Not allowed reduction identifier is found.
7218276479Sdim    Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier)
7219276479Sdim        << ReductionIdRange;
7220276479Sdim    return nullptr;
7221276479Sdim  }
7222276479Sdim
7223276479Sdim  SmallVector<Expr *, 8> Vars;
7224296417Sdim  SmallVector<Expr *, 8> Privates;
7225288943Sdim  SmallVector<Expr *, 8> LHSs;
7226288943Sdim  SmallVector<Expr *, 8> RHSs;
7227288943Sdim  SmallVector<Expr *, 8> ReductionOps;
7228276479Sdim  for (auto RefExpr : VarList) {
7229276479Sdim    assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
7230276479Sdim    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7231276479Sdim      // It will be analyzed later.
7232276479Sdim      Vars.push_back(RefExpr);
7233296417Sdim      Privates.push_back(nullptr);
7234288943Sdim      LHSs.push_back(nullptr);
7235288943Sdim      RHSs.push_back(nullptr);
7236288943Sdim      ReductionOps.push_back(nullptr);
7237276479Sdim      continue;
7238276479Sdim    }
7239276479Sdim
7240276479Sdim    if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
7241276479Sdim        RefExpr->isInstantiationDependent() ||
7242276479Sdim        RefExpr->containsUnexpandedParameterPack()) {
7243276479Sdim      // It will be analyzed later.
7244276479Sdim      Vars.push_back(RefExpr);
7245296417Sdim      Privates.push_back(nullptr);
7246288943Sdim      LHSs.push_back(nullptr);
7247288943Sdim      RHSs.push_back(nullptr);
7248288943Sdim      ReductionOps.push_back(nullptr);
7249276479Sdim      continue;
7250276479Sdim    }
7251276479Sdim
7252276479Sdim    auto ELoc = RefExpr->getExprLoc();
7253276479Sdim    auto ERange = RefExpr->getSourceRange();
7254276479Sdim    // OpenMP [2.1, C/C++]
7255276479Sdim    //  A list item is a variable or array section, subject to the restrictions
7256276479Sdim    //  specified in Section 2.4 on page 42 and in each of the sections
7257276479Sdim    // describing clauses and directives for which a list appears.
7258276479Sdim    // OpenMP  [2.14.3.3, Restrictions, p.1]
7259276479Sdim    //  A variable that is part of another variable (as an array or
7260276479Sdim    //  structure element) cannot appear in a private clause.
7261296417Sdim    auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
7262296417Sdim    auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr);
7263296417Sdim    auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr);
7264296417Sdim    if (!ASE && !OASE && (!DE || !isa<VarDecl>(DE->getDecl()))) {
7265296417Sdim      Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) << ERange;
7266276479Sdim      continue;
7267276479Sdim    }
7268296417Sdim    QualType Type;
7269296417Sdim    VarDecl *VD = nullptr;
7270296417Sdim    if (DE) {
7271296417Sdim      auto D = DE->getDecl();
7272296417Sdim      VD = cast<VarDecl>(D);
7273296417Sdim      Type = VD->getType();
7274296417Sdim    } else if (ASE) {
7275296417Sdim      Type = ASE->getType();
7276296417Sdim      auto *Base = ASE->getBase()->IgnoreParenImpCasts();
7277296417Sdim      while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
7278296417Sdim        Base = TempASE->getBase()->IgnoreParenImpCasts();
7279296417Sdim      DE = dyn_cast<DeclRefExpr>(Base);
7280296417Sdim      if (DE)
7281296417Sdim        VD = dyn_cast<VarDecl>(DE->getDecl());
7282296417Sdim      if (!VD) {
7283296417Sdim        Diag(Base->getExprLoc(), diag::err_omp_expected_base_var_name)
7284296417Sdim            << 0 << Base->getSourceRange();
7285296417Sdim        continue;
7286296417Sdim      }
7287296417Sdim    } else if (OASE) {
7288296417Sdim      auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
7289296417Sdim      if (auto *ATy = BaseType->getAsArrayTypeUnsafe())
7290296417Sdim        Type = ATy->getElementType();
7291296417Sdim      else
7292296417Sdim        Type = BaseType->getPointeeType();
7293296417Sdim      auto *Base = OASE->getBase()->IgnoreParenImpCasts();
7294296417Sdim      while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
7295296417Sdim        Base = TempOASE->getBase()->IgnoreParenImpCasts();
7296296417Sdim      while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
7297296417Sdim        Base = TempASE->getBase()->IgnoreParenImpCasts();
7298296417Sdim      DE = dyn_cast<DeclRefExpr>(Base);
7299296417Sdim      if (DE)
7300296417Sdim        VD = dyn_cast<VarDecl>(DE->getDecl());
7301296417Sdim      if (!VD) {
7302296417Sdim        Diag(Base->getExprLoc(), diag::err_omp_expected_base_var_name)
7303296417Sdim            << 1 << Base->getSourceRange();
7304296417Sdim        continue;
7305296417Sdim      }
7306296417Sdim    }
7307296417Sdim
7308276479Sdim    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
7309276479Sdim    //  A variable that appears in a private clause must not have an incomplete
7310276479Sdim    //  type or a reference type.
7311276479Sdim    if (RequireCompleteType(ELoc, Type,
7312276479Sdim                            diag::err_omp_reduction_incomplete_type))
7313276479Sdim      continue;
7314276479Sdim    // OpenMP [2.14.3.6, reduction clause, Restrictions]
7315276479Sdim    // Arrays may not appear in a reduction clause.
7316276479Sdim    if (Type.getNonReferenceType()->isArrayType()) {
7317276479Sdim      Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange;
7318296417Sdim      if (!ASE && !OASE) {
7319296417Sdim        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7320296417Sdim                      VarDecl::DeclarationOnly;
7321296417Sdim        Diag(VD->getLocation(),
7322296417Sdim             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7323296417Sdim            << VD;
7324296417Sdim      }
7325276479Sdim      continue;
7326276479Sdim    }
7327276479Sdim    // OpenMP [2.14.3.6, reduction clause, Restrictions]
7328276479Sdim    // A list item that appears in a reduction clause must not be
7329276479Sdim    // const-qualified.
7330276479Sdim    if (Type.getNonReferenceType().isConstant(Context)) {
7331296417Sdim      Diag(ELoc, diag::err_omp_const_reduction_list_item)
7332276479Sdim          << getOpenMPClauseName(OMPC_reduction) << Type << ERange;
7333296417Sdim      if (!ASE && !OASE) {
7334296417Sdim        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7335296417Sdim                      VarDecl::DeclarationOnly;
7336296417Sdim        Diag(VD->getLocation(),
7337296417Sdim             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7338296417Sdim            << VD;
7339296417Sdim      }
7340276479Sdim      continue;
7341276479Sdim    }
7342276479Sdim    // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
7343276479Sdim    //  If a list-item is a reference type then it must bind to the same object
7344276479Sdim    //  for all threads of the team.
7345296417Sdim    if (!ASE && !OASE) {
7346296417Sdim      VarDecl *VDDef = VD->getDefinition();
7347296417Sdim      if (Type->isReferenceType() && VDDef) {
7348296417Sdim        DSARefChecker Check(DSAStack);
7349296417Sdim        if (Check.Visit(VDDef->getInit())) {
7350296417Sdim          Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
7351296417Sdim          Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
7352296417Sdim          continue;
7353296417Sdim        }
7354276479Sdim      }
7355276479Sdim    }
7356276479Sdim    // OpenMP [2.14.3.6, reduction clause, Restrictions]
7357276479Sdim    // The type of a list item that appears in a reduction clause must be valid
7358276479Sdim    // for the reduction-identifier. For a max or min reduction in C, the type
7359276479Sdim    // of the list item must be an allowed arithmetic data type: char, int,
7360276479Sdim    // float, double, or _Bool, possibly modified with long, short, signed, or
7361276479Sdim    // unsigned. For a max or min reduction in C++, the type of the list item
7362276479Sdim    // must be an allowed arithmetic data type: char, wchar_t, int, float,
7363276479Sdim    // double, or bool, possibly modified with long, short, signed, or unsigned.
7364276479Sdim    if ((BOK == BO_GT || BOK == BO_LT) &&
7365276479Sdim        !(Type->isScalarType() ||
7366276479Sdim          (getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
7367276479Sdim      Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
7368276479Sdim          << getLangOpts().CPlusPlus;
7369296417Sdim      if (!ASE && !OASE) {
7370296417Sdim        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7371296417Sdim                      VarDecl::DeclarationOnly;
7372296417Sdim        Diag(VD->getLocation(),
7373296417Sdim             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7374296417Sdim            << VD;
7375296417Sdim      }
7376276479Sdim      continue;
7377276479Sdim    }
7378276479Sdim    if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
7379276479Sdim        !getLangOpts().CPlusPlus && Type->isFloatingType()) {
7380276479Sdim      Diag(ELoc, diag::err_omp_clause_floating_type_arg);
7381296417Sdim      if (!ASE && !OASE) {
7382296417Sdim        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7383296417Sdim                      VarDecl::DeclarationOnly;
7384296417Sdim        Diag(VD->getLocation(),
7385296417Sdim             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7386296417Sdim            << VD;
7387296417Sdim      }
7388276479Sdim      continue;
7389276479Sdim    }
7390276479Sdim    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
7391276479Sdim    // in a Construct]
7392276479Sdim    //  Variables with the predetermined data-sharing attributes may not be
7393276479Sdim    //  listed in data-sharing attributes clauses, except for the cases
7394276479Sdim    //  listed below. For these exceptions only, listing a predetermined
7395276479Sdim    //  variable in a data-sharing attribute clause is allowed and overrides
7396276479Sdim    //  the variable's predetermined data-sharing attributes.
7397276479Sdim    // OpenMP [2.14.3.6, Restrictions, p.3]
7398276479Sdim    //  Any number of reduction clauses can be specified on the directive,
7399276479Sdim    //  but a list item can appear only once in the reduction clauses for that
7400276479Sdim    //  directive.
7401296417Sdim    DSAStackTy::DSAVarData DVar;
7402296417Sdim    DVar = DSAStack->getTopDSA(VD, false);
7403276479Sdim    if (DVar.CKind == OMPC_reduction) {
7404276479Sdim      Diag(ELoc, diag::err_omp_once_referenced)
7405276479Sdim          << getOpenMPClauseName(OMPC_reduction);
7406276479Sdim      if (DVar.RefExpr) {
7407276479Sdim        Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
7408276479Sdim      }
7409276479Sdim    } else if (DVar.CKind != OMPC_unknown) {
7410276479Sdim      Diag(ELoc, diag::err_omp_wrong_dsa)
7411276479Sdim          << getOpenMPClauseName(DVar.CKind)
7412276479Sdim          << getOpenMPClauseName(OMPC_reduction);
7413276479Sdim      ReportOriginalDSA(*this, DSAStack, VD, DVar);
7414276479Sdim      continue;
7415276479Sdim    }
7416276479Sdim
7417276479Sdim    // OpenMP [2.14.3.6, Restrictions, p.1]
7418276479Sdim    //  A list item that appears in a reduction clause of a worksharing
7419276479Sdim    //  construct must be shared in the parallel regions to which any of the
7420276479Sdim    //  worksharing regions arising from the worksharing construct bind.
7421276479Sdim    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
7422276479Sdim    if (isOpenMPWorksharingDirective(CurrDir) &&
7423276479Sdim        !isOpenMPParallelDirective(CurrDir)) {
7424276479Sdim      DVar = DSAStack->getImplicitDSA(VD, true);
7425276479Sdim      if (DVar.CKind != OMPC_shared) {
7426276479Sdim        Diag(ELoc, diag::err_omp_required_access)
7427276479Sdim            << getOpenMPClauseName(OMPC_reduction)
7428276479Sdim            << getOpenMPClauseName(OMPC_shared);
7429276479Sdim        ReportOriginalDSA(*this, DSAStack, VD, DVar);
7430276479Sdim        continue;
7431276479Sdim      }
7432276479Sdim    }
7433296417Sdim
7434288943Sdim    Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
7435296417Sdim    auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs",
7436296417Sdim                               VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7437296417Sdim    auto *RHSVD = buildVarDecl(*this, ELoc, Type, VD->getName(),
7438296417Sdim                               VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7439296417Sdim    auto PrivateTy = Type;
7440296417Sdim    if (OASE) {
7441296417Sdim      // For array sections only:
7442296417Sdim      // Create pseudo array type for private copy. The size for this array will
7443296417Sdim      // be generated during codegen.
7444296417Sdim      // For array subscripts or single variables Private Ty is the same as Type
7445296417Sdim      // (type of the variable or single array element).
7446296417Sdim      PrivateTy = Context.getVariableArrayType(
7447296417Sdim          Type, new (Context) OpaqueValueExpr(SourceLocation(),
7448296417Sdim                                              Context.getSizeType(), VK_RValue),
7449296417Sdim          ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
7450296417Sdim    }
7451296417Sdim    // Private copy.
7452296417Sdim    auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, VD->getName(),
7453296417Sdim                                   VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7454288943Sdim    // Add initializer for private variable.
7455288943Sdim    Expr *Init = nullptr;
7456288943Sdim    switch (BOK) {
7457288943Sdim    case BO_Add:
7458288943Sdim    case BO_Xor:
7459288943Sdim    case BO_Or:
7460288943Sdim    case BO_LOr:
7461288943Sdim      // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
7462288943Sdim      if (Type->isScalarType() || Type->isAnyComplexType()) {
7463288943Sdim        Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get();
7464276479Sdim      }
7465288943Sdim      break;
7466288943Sdim    case BO_Mul:
7467288943Sdim    case BO_LAnd:
7468288943Sdim      if (Type->isScalarType() || Type->isAnyComplexType()) {
7469288943Sdim        // '*' and '&&' reduction ops - initializer is '1'.
7470288943Sdim        Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get();
7471288943Sdim      }
7472288943Sdim      break;
7473288943Sdim    case BO_And: {
7474288943Sdim      // '&' reduction op - initializer is '~0'.
7475288943Sdim      QualType OrigType = Type;
7476288943Sdim      if (auto *ComplexTy = OrigType->getAs<ComplexType>()) {
7477288943Sdim        Type = ComplexTy->getElementType();
7478288943Sdim      }
7479288943Sdim      if (Type->isRealFloatingType()) {
7480288943Sdim        llvm::APFloat InitValue =
7481288943Sdim            llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
7482288943Sdim                                           /*isIEEE=*/true);
7483288943Sdim        Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
7484288943Sdim                                       Type, ELoc);
7485288943Sdim      } else if (Type->isScalarType()) {
7486288943Sdim        auto Size = Context.getTypeSize(Type);
7487288943Sdim        QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
7488288943Sdim        llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
7489288943Sdim        Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
7490288943Sdim      }
7491288943Sdim      if (Init && OrigType->isAnyComplexType()) {
7492288943Sdim        // Init = 0xFFFF + 0xFFFFi;
7493288943Sdim        auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
7494288943Sdim        Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
7495288943Sdim      }
7496288943Sdim      Type = OrigType;
7497288943Sdim      break;
7498288943Sdim    }
7499288943Sdim    case BO_LT:
7500288943Sdim    case BO_GT: {
7501288943Sdim      // 'min' reduction op - initializer is 'Largest representable number in
7502288943Sdim      // the reduction list item type'.
7503288943Sdim      // 'max' reduction op - initializer is 'Least representable number in
7504288943Sdim      // the reduction list item type'.
7505288943Sdim      if (Type->isIntegerType() || Type->isPointerType()) {
7506288943Sdim        bool IsSigned = Type->hasSignedIntegerRepresentation();
7507288943Sdim        auto Size = Context.getTypeSize(Type);
7508288943Sdim        QualType IntTy =
7509288943Sdim            Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
7510288943Sdim        llvm::APInt InitValue =
7511288943Sdim            (BOK != BO_LT)
7512288943Sdim                ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
7513288943Sdim                           : llvm::APInt::getMinValue(Size)
7514288943Sdim                : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
7515288943Sdim                           : llvm::APInt::getMaxValue(Size);
7516288943Sdim        Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
7517288943Sdim        if (Type->isPointerType()) {
7518288943Sdim          // Cast to pointer type.
7519288943Sdim          auto CastExpr = BuildCStyleCastExpr(
7520288943Sdim              SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc),
7521288943Sdim              SourceLocation(), Init);
7522288943Sdim          if (CastExpr.isInvalid())
7523288943Sdim            continue;
7524288943Sdim          Init = CastExpr.get();
7525276479Sdim        }
7526288943Sdim      } else if (Type->isRealFloatingType()) {
7527288943Sdim        llvm::APFloat InitValue = llvm::APFloat::getLargest(
7528288943Sdim            Context.getFloatTypeSemantics(Type), BOK != BO_LT);
7529288943Sdim        Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
7530288943Sdim                                       Type, ELoc);
7531276479Sdim      }
7532288943Sdim      break;
7533276479Sdim    }
7534288943Sdim    case BO_PtrMemD:
7535288943Sdim    case BO_PtrMemI:
7536288943Sdim    case BO_MulAssign:
7537288943Sdim    case BO_Div:
7538288943Sdim    case BO_Rem:
7539288943Sdim    case BO_Sub:
7540288943Sdim    case BO_Shl:
7541288943Sdim    case BO_Shr:
7542288943Sdim    case BO_LE:
7543288943Sdim    case BO_GE:
7544288943Sdim    case BO_EQ:
7545288943Sdim    case BO_NE:
7546288943Sdim    case BO_AndAssign:
7547288943Sdim    case BO_XorAssign:
7548288943Sdim    case BO_OrAssign:
7549288943Sdim    case BO_Assign:
7550288943Sdim    case BO_AddAssign:
7551288943Sdim    case BO_SubAssign:
7552288943Sdim    case BO_DivAssign:
7553288943Sdim    case BO_RemAssign:
7554288943Sdim    case BO_ShlAssign:
7555288943Sdim    case BO_ShrAssign:
7556288943Sdim    case BO_Comma:
7557288943Sdim      llvm_unreachable("Unexpected reduction operation");
7558288943Sdim    }
7559288943Sdim    if (Init) {
7560288943Sdim      AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false,
7561288943Sdim                           /*TypeMayContainAuto=*/false);
7562296417Sdim    } else
7563288943Sdim      ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false);
7564288943Sdim    if (!RHSVD->hasInit()) {
7565288943Sdim      Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
7566288943Sdim                                                            << ReductionIdRange;
7567296417Sdim      if (VD) {
7568296417Sdim        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7569296417Sdim                      VarDecl::DeclarationOnly;
7570296417Sdim        Diag(VD->getLocation(),
7571296417Sdim             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7572296417Sdim            << VD;
7573296417Sdim      }
7574288943Sdim      continue;
7575288943Sdim    }
7576296417Sdim    // Store initializer for single element in private copy. Will be used during
7577296417Sdim    // codegen.
7578296417Sdim    PrivateVD->setInit(RHSVD->getInit());
7579296417Sdim    PrivateVD->setInitStyle(RHSVD->getInitStyle());
7580288943Sdim    auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc);
7581288943Sdim    auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc);
7582296417Sdim    auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc);
7583288943Sdim    ExprResult ReductionOp =
7584288943Sdim        BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK,
7585288943Sdim                   LHSDRE, RHSDRE);
7586288943Sdim    if (ReductionOp.isUsable()) {
7587288943Sdim      if (BOK != BO_LT && BOK != BO_GT) {
7588288943Sdim        ReductionOp =
7589288943Sdim            BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
7590288943Sdim                       BO_Assign, LHSDRE, ReductionOp.get());
7591288943Sdim      } else {
7592288943Sdim        auto *ConditionalOp = new (Context) ConditionalOperator(
7593288943Sdim            ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(),
7594288943Sdim            RHSDRE, Type, VK_LValue, OK_Ordinary);
7595288943Sdim        ReductionOp =
7596288943Sdim            BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
7597288943Sdim                       BO_Assign, LHSDRE, ConditionalOp);
7598288943Sdim      }
7599296417Sdim      ReductionOp = ActOnFinishFullExpr(ReductionOp.get());
7600288943Sdim    }
7601288943Sdim    if (ReductionOp.isInvalid())
7602288943Sdim      continue;
7603276479Sdim
7604276479Sdim    DSAStack->addDSA(VD, DE, OMPC_reduction);
7605296417Sdim    Vars.push_back(RefExpr);
7606296417Sdim    Privates.push_back(PrivateDRE);
7607288943Sdim    LHSs.push_back(LHSDRE);
7608288943Sdim    RHSs.push_back(RHSDRE);
7609288943Sdim    ReductionOps.push_back(ReductionOp.get());
7610276479Sdim  }
7611276479Sdim
7612276479Sdim  if (Vars.empty())
7613276479Sdim    return nullptr;
7614276479Sdim
7615276479Sdim  return OMPReductionClause::Create(
7616276479Sdim      Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
7617296417Sdim      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates,
7618296417Sdim      LHSs, RHSs, ReductionOps);
7619276479Sdim}
7620276479Sdim
7621296417SdimOMPClause *Sema::ActOnOpenMPLinearClause(
7622296417Sdim    ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
7623296417Sdim    SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
7624296417Sdim    SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
7625276479Sdim  SmallVector<Expr *, 8> Vars;
7626296417Sdim  SmallVector<Expr *, 8> Privates;
7627288943Sdim  SmallVector<Expr *, 8> Inits;
7628296417Sdim  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
7629296417Sdim      LinKind == OMPC_LINEAR_unknown) {
7630296417Sdim    Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
7631296417Sdim    LinKind = OMPC_LINEAR_val;
7632296417Sdim  }
7633276479Sdim  for (auto &RefExpr : VarList) {
7634276479Sdim    assert(RefExpr && "NULL expr in OpenMP linear clause.");
7635276479Sdim    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7636276479Sdim      // It will be analyzed later.
7637276479Sdim      Vars.push_back(RefExpr);
7638296417Sdim      Privates.push_back(nullptr);
7639288943Sdim      Inits.push_back(nullptr);
7640276479Sdim      continue;
7641276479Sdim    }
7642276479Sdim
7643276479Sdim    // OpenMP [2.14.3.7, linear clause]
7644276479Sdim    // A list item that appears in a linear clause is subject to the private
7645276479Sdim    // clause semantics described in Section 2.14.3.3 on page 159 except as
7646276479Sdim    // noted. In addition, the value of the new list item on each iteration
7647276479Sdim    // of the associated loop(s) corresponds to the value of the original
7648276479Sdim    // list item before entering the construct plus the logical number of
7649276479Sdim    // the iteration times linear-step.
7650276479Sdim
7651276479Sdim    SourceLocation ELoc = RefExpr->getExprLoc();
7652276479Sdim    // OpenMP [2.1, C/C++]
7653276479Sdim    //  A list item is a variable name.
7654276479Sdim    // OpenMP  [2.14.3.3, Restrictions, p.1]
7655276479Sdim    //  A variable that is part of another variable (as an array or
7656276479Sdim    //  structure element) cannot appear in a private clause.
7657276479Sdim    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
7658276479Sdim    if (!DE || !isa<VarDecl>(DE->getDecl())) {
7659276479Sdim      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7660276479Sdim      continue;
7661276479Sdim    }
7662276479Sdim
7663276479Sdim    VarDecl *VD = cast<VarDecl>(DE->getDecl());
7664276479Sdim
7665276479Sdim    // OpenMP [2.14.3.7, linear clause]
7666276479Sdim    //  A list-item cannot appear in more than one linear clause.
7667276479Sdim    //  A list-item that appears in a linear clause cannot appear in any
7668276479Sdim    //  other data-sharing attribute clause.
7669276479Sdim    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
7670276479Sdim    if (DVar.RefExpr) {
7671276479Sdim      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
7672276479Sdim                                          << getOpenMPClauseName(OMPC_linear);
7673276479Sdim      ReportOriginalDSA(*this, DSAStack, VD, DVar);
7674276479Sdim      continue;
7675276479Sdim    }
7676276479Sdim
7677276479Sdim    QualType QType = VD->getType();
7678276479Sdim    if (QType->isDependentType() || QType->isInstantiationDependentType()) {
7679276479Sdim      // It will be analyzed later.
7680276479Sdim      Vars.push_back(DE);
7681296417Sdim      Privates.push_back(nullptr);
7682288943Sdim      Inits.push_back(nullptr);
7683276479Sdim      continue;
7684276479Sdim    }
7685276479Sdim
7686276479Sdim    // A variable must not have an incomplete type or a reference type.
7687276479Sdim    if (RequireCompleteType(ELoc, QType,
7688276479Sdim                            diag::err_omp_linear_incomplete_type)) {
7689276479Sdim      continue;
7690276479Sdim    }
7691296417Sdim    if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
7692296417Sdim        !QType->isReferenceType()) {
7693296417Sdim      Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
7694296417Sdim          << QType << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
7695276479Sdim      continue;
7696276479Sdim    }
7697296417Sdim    QType = QType.getNonReferenceType();
7698276479Sdim
7699276479Sdim    // A list item must not be const-qualified.
7700276479Sdim    if (QType.isConstant(Context)) {
7701276479Sdim      Diag(ELoc, diag::err_omp_const_variable)
7702276479Sdim          << getOpenMPClauseName(OMPC_linear);
7703276479Sdim      bool IsDecl =
7704276479Sdim          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
7705276479Sdim      Diag(VD->getLocation(),
7706276479Sdim           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7707276479Sdim          << VD;
7708276479Sdim      continue;
7709276479Sdim    }
7710276479Sdim
7711276479Sdim    // A list item must be of integral or pointer type.
7712276479Sdim    QType = QType.getUnqualifiedType().getCanonicalType();
7713276479Sdim    const Type *Ty = QType.getTypePtrOrNull();
7714276479Sdim    if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
7715276479Sdim                !Ty->isPointerType())) {
7716276479Sdim      Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType;
7717276479Sdim      bool IsDecl =
7718276479Sdim          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
7719276479Sdim      Diag(VD->getLocation(),
7720276479Sdim           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7721276479Sdim          << VD;
7722276479Sdim      continue;
7723276479Sdim    }
7724276479Sdim
7725296417Sdim    // Build private copy of original var.
7726296417Sdim    auto *Private = buildVarDecl(*this, ELoc, QType, VD->getName(),
7727296417Sdim                                 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7728296417Sdim    auto *PrivateRef = buildDeclRefExpr(
7729296417Sdim        *this, Private, DE->getType().getUnqualifiedType(), DE->getExprLoc());
7730288943Sdim    // Build var to save initial value.
7731288943Sdim    VarDecl *Init = buildVarDecl(*this, ELoc, QType, ".linear.start");
7732296417Sdim    Expr *InitExpr;
7733296417Sdim    if (LinKind == OMPC_LINEAR_uval)
7734296417Sdim      InitExpr = VD->getInit();
7735296417Sdim    else
7736296417Sdim      InitExpr = DE;
7737296417Sdim    AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
7738288943Sdim                         /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
7739288943Sdim    auto InitRef = buildDeclRefExpr(
7740288943Sdim        *this, Init, DE->getType().getUnqualifiedType(), DE->getExprLoc());
7741276479Sdim    DSAStack->addDSA(VD, DE, OMPC_linear);
7742276479Sdim    Vars.push_back(DE);
7743296417Sdim    Privates.push_back(PrivateRef);
7744288943Sdim    Inits.push_back(InitRef);
7745276479Sdim  }
7746276479Sdim
7747276479Sdim  if (Vars.empty())
7748276479Sdim    return nullptr;
7749276479Sdim
7750276479Sdim  Expr *StepExpr = Step;
7751288943Sdim  Expr *CalcStepExpr = nullptr;
7752276479Sdim  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
7753276479Sdim      !Step->isInstantiationDependent() &&
7754276479Sdim      !Step->containsUnexpandedParameterPack()) {
7755276479Sdim    SourceLocation StepLoc = Step->getLocStart();
7756276479Sdim    ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
7757276479Sdim    if (Val.isInvalid())
7758276479Sdim      return nullptr;
7759276479Sdim    StepExpr = Val.get();
7760276479Sdim
7761288943Sdim    // Build var to save the step value.
7762288943Sdim    VarDecl *SaveVar =
7763288943Sdim        buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
7764288943Sdim    ExprResult SaveRef =
7765288943Sdim        buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
7766288943Sdim    ExprResult CalcStep =
7767288943Sdim        BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
7768296417Sdim    CalcStep = ActOnFinishFullExpr(CalcStep.get());
7769288943Sdim
7770276479Sdim    // Warn about zero linear step (it would be probably better specified as
7771276479Sdim    // making corresponding variables 'const').
7772276479Sdim    llvm::APSInt Result;
7773288943Sdim    bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
7774288943Sdim    if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
7775276479Sdim      Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
7776276479Sdim                                                     << (Vars.size() > 1);
7777288943Sdim    if (!IsConstant && CalcStep.isUsable()) {
7778288943Sdim      // Calculate the step beforehand instead of doing this on each iteration.
7779288943Sdim      // (This is not used if the number of iterations may be kfold-ed).
7780288943Sdim      CalcStepExpr = CalcStep.get();
7781288943Sdim    }
7782276479Sdim  }
7783276479Sdim
7784296417Sdim  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
7785296417Sdim                                 ColonLoc, EndLoc, Vars, Privates, Inits,
7786296417Sdim                                 StepExpr, CalcStepExpr);
7787276479Sdim}
7788276479Sdim
7789288943Sdimstatic bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
7790288943Sdim                                     Expr *NumIterations, Sema &SemaRef,
7791288943Sdim                                     Scope *S) {
7792288943Sdim  // Walk the vars and build update/final expressions for the CodeGen.
7793288943Sdim  SmallVector<Expr *, 8> Updates;
7794288943Sdim  SmallVector<Expr *, 8> Finals;
7795288943Sdim  Expr *Step = Clause.getStep();
7796288943Sdim  Expr *CalcStep = Clause.getCalcStep();
7797288943Sdim  // OpenMP [2.14.3.7, linear clause]
7798288943Sdim  // If linear-step is not specified it is assumed to be 1.
7799288943Sdim  if (Step == nullptr)
7800288943Sdim    Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
7801288943Sdim  else if (CalcStep)
7802288943Sdim    Step = cast<BinaryOperator>(CalcStep)->getLHS();
7803288943Sdim  bool HasErrors = false;
7804288943Sdim  auto CurInit = Clause.inits().begin();
7805296417Sdim  auto CurPrivate = Clause.privates().begin();
7806296417Sdim  auto LinKind = Clause.getModifier();
7807288943Sdim  for (auto &RefExpr : Clause.varlists()) {
7808288943Sdim    Expr *InitExpr = *CurInit;
7809288943Sdim
7810288943Sdim    // Build privatized reference to the current linear var.
7811288943Sdim    auto DE = cast<DeclRefExpr>(RefExpr);
7812296417Sdim    Expr *CapturedRef;
7813296417Sdim    if (LinKind == OMPC_LINEAR_uval)
7814296417Sdim      CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
7815296417Sdim    else
7816296417Sdim      CapturedRef =
7817296417Sdim          buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
7818296417Sdim                           DE->getType().getUnqualifiedType(), DE->getExprLoc(),
7819296417Sdim                           /*RefersToCapture=*/true);
7820288943Sdim
7821288943Sdim    // Build update: Var = InitExpr + IV * Step
7822288943Sdim    ExprResult Update =
7823296417Sdim        BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
7824288943Sdim                           InitExpr, IV, Step, /* Subtract */ false);
7825296417Sdim    Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
7826296417Sdim                                         /*DiscardedValue=*/true);
7827288943Sdim
7828288943Sdim    // Build final: Var = InitExpr + NumIterations * Step
7829288943Sdim    ExprResult Final =
7830296417Sdim        BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
7831288943Sdim                           InitExpr, NumIterations, Step, /* Subtract */ false);
7832296417Sdim    Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
7833296417Sdim                                        /*DiscardedValue=*/true);
7834288943Sdim    if (!Update.isUsable() || !Final.isUsable()) {
7835288943Sdim      Updates.push_back(nullptr);
7836288943Sdim      Finals.push_back(nullptr);
7837288943Sdim      HasErrors = true;
7838288943Sdim    } else {
7839288943Sdim      Updates.push_back(Update.get());
7840288943Sdim      Finals.push_back(Final.get());
7841288943Sdim    }
7842296417Sdim    ++CurInit, ++CurPrivate;
7843288943Sdim  }
7844288943Sdim  Clause.setUpdates(Updates);
7845288943Sdim  Clause.setFinals(Finals);
7846288943Sdim  return HasErrors;
7847288943Sdim}
7848288943Sdim
7849276479SdimOMPClause *Sema::ActOnOpenMPAlignedClause(
7850276479Sdim    ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
7851276479Sdim    SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
7852276479Sdim
7853276479Sdim  SmallVector<Expr *, 8> Vars;
7854276479Sdim  for (auto &RefExpr : VarList) {
7855276479Sdim    assert(RefExpr && "NULL expr in OpenMP aligned clause.");
7856276479Sdim    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7857276479Sdim      // It will be analyzed later.
7858276479Sdim      Vars.push_back(RefExpr);
7859276479Sdim      continue;
7860276479Sdim    }
7861276479Sdim
7862276479Sdim    SourceLocation ELoc = RefExpr->getExprLoc();
7863276479Sdim    // OpenMP [2.1, C/C++]
7864276479Sdim    //  A list item is a variable name.
7865276479Sdim    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
7866276479Sdim    if (!DE || !isa<VarDecl>(DE->getDecl())) {
7867276479Sdim      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7868276479Sdim      continue;
7869276479Sdim    }
7870276479Sdim
7871276479Sdim    VarDecl *VD = cast<VarDecl>(DE->getDecl());
7872276479Sdim
7873276479Sdim    // OpenMP  [2.8.1, simd construct, Restrictions]
7874276479Sdim    // The type of list items appearing in the aligned clause must be
7875276479Sdim    // array, pointer, reference to array, or reference to pointer.
7876288943Sdim    QualType QType = VD->getType();
7877288943Sdim    QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
7878276479Sdim    const Type *Ty = QType.getTypePtrOrNull();
7879276479Sdim    if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() &&
7880276479Sdim                !Ty->isPointerType())) {
7881276479Sdim      Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
7882276479Sdim          << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange();
7883276479Sdim      bool IsDecl =
7884276479Sdim          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
7885276479Sdim      Diag(VD->getLocation(),
7886276479Sdim           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7887276479Sdim          << VD;
7888276479Sdim      continue;
7889276479Sdim    }
7890276479Sdim
7891276479Sdim    // OpenMP  [2.8.1, simd construct, Restrictions]
7892276479Sdim    // A list-item cannot appear in more than one aligned clause.
7893276479Sdim    if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) {
7894276479Sdim      Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
7895276479Sdim      Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
7896276479Sdim          << getOpenMPClauseName(OMPC_aligned);
7897276479Sdim      continue;
7898276479Sdim    }
7899276479Sdim
7900276479Sdim    Vars.push_back(DE);
7901276479Sdim  }
7902276479Sdim
7903276479Sdim  // OpenMP [2.8.1, simd construct, Description]
7904276479Sdim  // The parameter of the aligned clause, alignment, must be a constant
7905276479Sdim  // positive integer expression.
7906276479Sdim  // If no optional parameter is specified, implementation-defined default
7907276479Sdim  // alignments for SIMD instructions on the target platforms are assumed.
7908276479Sdim  if (Alignment != nullptr) {
7909276479Sdim    ExprResult AlignResult =
7910276479Sdim        VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
7911276479Sdim    if (AlignResult.isInvalid())
7912276479Sdim      return nullptr;
7913276479Sdim    Alignment = AlignResult.get();
7914276479Sdim  }
7915276479Sdim  if (Vars.empty())
7916276479Sdim    return nullptr;
7917276479Sdim
7918276479Sdim  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
7919276479Sdim                                  EndLoc, Vars, Alignment);
7920276479Sdim}
7921276479Sdim
7922276479SdimOMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
7923276479Sdim                                         SourceLocation StartLoc,
7924276479Sdim                                         SourceLocation LParenLoc,
7925276479Sdim                                         SourceLocation EndLoc) {
7926276479Sdim  SmallVector<Expr *, 8> Vars;
7927288943Sdim  SmallVector<Expr *, 8> SrcExprs;
7928288943Sdim  SmallVector<Expr *, 8> DstExprs;
7929288943Sdim  SmallVector<Expr *, 8> AssignmentOps;
7930276479Sdim  for (auto &RefExpr : VarList) {
7931276479Sdim    assert(RefExpr && "NULL expr in OpenMP copyin clause.");
7932276479Sdim    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7933276479Sdim      // It will be analyzed later.
7934276479Sdim      Vars.push_back(RefExpr);
7935288943Sdim      SrcExprs.push_back(nullptr);
7936288943Sdim      DstExprs.push_back(nullptr);
7937288943Sdim      AssignmentOps.push_back(nullptr);
7938276479Sdim      continue;
7939276479Sdim    }
7940276479Sdim
7941276479Sdim    SourceLocation ELoc = RefExpr->getExprLoc();
7942276479Sdim    // OpenMP [2.1, C/C++]
7943276479Sdim    //  A list item is a variable name.
7944276479Sdim    // OpenMP  [2.14.4.1, Restrictions, p.1]
7945276479Sdim    //  A list item that appears in a copyin clause must be threadprivate.
7946276479Sdim    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
7947276479Sdim    if (!DE || !isa<VarDecl>(DE->getDecl())) {
7948276479Sdim      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7949276479Sdim      continue;
7950276479Sdim    }
7951276479Sdim
7952276479Sdim    Decl *D = DE->getDecl();
7953276479Sdim    VarDecl *VD = cast<VarDecl>(D);
7954276479Sdim
7955276479Sdim    QualType Type = VD->getType();
7956276479Sdim    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
7957276479Sdim      // It will be analyzed later.
7958276479Sdim      Vars.push_back(DE);
7959288943Sdim      SrcExprs.push_back(nullptr);
7960288943Sdim      DstExprs.push_back(nullptr);
7961288943Sdim      AssignmentOps.push_back(nullptr);
7962276479Sdim      continue;
7963276479Sdim    }
7964276479Sdim
7965276479Sdim    // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
7966276479Sdim    //  A list item that appears in a copyin clause must be threadprivate.
7967276479Sdim    if (!DSAStack->isThreadPrivate(VD)) {
7968276479Sdim      Diag(ELoc, diag::err_omp_required_access)
7969276479Sdim          << getOpenMPClauseName(OMPC_copyin)
7970276479Sdim          << getOpenMPDirectiveName(OMPD_threadprivate);
7971276479Sdim      continue;
7972276479Sdim    }
7973276479Sdim
7974276479Sdim    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
7975276479Sdim    //  A variable of class type (or array thereof) that appears in a
7976276479Sdim    //  copyin clause requires an accessible, unambiguous copy assignment
7977276479Sdim    //  operator for the class type.
7978288943Sdim    auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
7979296417Sdim    auto *SrcVD =
7980296417Sdim        buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(),
7981296417Sdim                     ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7982288943Sdim    auto *PseudoSrcExpr = buildDeclRefExpr(
7983288943Sdim        *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
7984288943Sdim    auto *DstVD =
7985296417Sdim        buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst",
7986296417Sdim                     VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7987288943Sdim    auto *PseudoDstExpr =
7988288943Sdim        buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
7989288943Sdim    // For arrays generate assignment operation for single element and replace
7990288943Sdim    // it by the original array element in CodeGen.
7991288943Sdim    auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
7992288943Sdim                                   PseudoDstExpr, PseudoSrcExpr);
7993288943Sdim    if (AssignmentOp.isInvalid())
7994288943Sdim      continue;
7995288943Sdim    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
7996288943Sdim                                       /*DiscardedValue=*/true);
7997288943Sdim    if (AssignmentOp.isInvalid())
7998288943Sdim      continue;
7999276479Sdim
8000276479Sdim    DSAStack->addDSA(VD, DE, OMPC_copyin);
8001276479Sdim    Vars.push_back(DE);
8002288943Sdim    SrcExprs.push_back(PseudoSrcExpr);
8003288943Sdim    DstExprs.push_back(PseudoDstExpr);
8004288943Sdim    AssignmentOps.push_back(AssignmentOp.get());
8005276479Sdim  }
8006276479Sdim
8007276479Sdim  if (Vars.empty())
8008276479Sdim    return nullptr;
8009276479Sdim
8010288943Sdim  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
8011288943Sdim                                 SrcExprs, DstExprs, AssignmentOps);
8012276479Sdim}
8013276479Sdim
8014276479SdimOMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
8015276479Sdim                                              SourceLocation StartLoc,
8016276479Sdim                                              SourceLocation LParenLoc,
8017276479Sdim                                              SourceLocation EndLoc) {
8018276479Sdim  SmallVector<Expr *, 8> Vars;
8019288943Sdim  SmallVector<Expr *, 8> SrcExprs;
8020288943Sdim  SmallVector<Expr *, 8> DstExprs;
8021288943Sdim  SmallVector<Expr *, 8> AssignmentOps;
8022276479Sdim  for (auto &RefExpr : VarList) {
8023276479Sdim    assert(RefExpr && "NULL expr in OpenMP copyprivate clause.");
8024276479Sdim    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
8025276479Sdim      // It will be analyzed later.
8026276479Sdim      Vars.push_back(RefExpr);
8027288943Sdim      SrcExprs.push_back(nullptr);
8028288943Sdim      DstExprs.push_back(nullptr);
8029288943Sdim      AssignmentOps.push_back(nullptr);
8030276479Sdim      continue;
8031276479Sdim    }
8032276479Sdim
8033276479Sdim    SourceLocation ELoc = RefExpr->getExprLoc();
8034276479Sdim    // OpenMP [2.1, C/C++]
8035276479Sdim    //  A list item is a variable name.
8036276479Sdim    // OpenMP  [2.14.4.1, Restrictions, p.1]
8037276479Sdim    //  A list item that appears in a copyin clause must be threadprivate.
8038276479Sdim    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
8039276479Sdim    if (!DE || !isa<VarDecl>(DE->getDecl())) {
8040276479Sdim      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
8041276479Sdim      continue;
8042276479Sdim    }
8043276479Sdim
8044276479Sdim    Decl *D = DE->getDecl();
8045276479Sdim    VarDecl *VD = cast<VarDecl>(D);
8046276479Sdim
8047276479Sdim    QualType Type = VD->getType();
8048276479Sdim    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
8049276479Sdim      // It will be analyzed later.
8050276479Sdim      Vars.push_back(DE);
8051288943Sdim      SrcExprs.push_back(nullptr);
8052288943Sdim      DstExprs.push_back(nullptr);
8053288943Sdim      AssignmentOps.push_back(nullptr);
8054276479Sdim      continue;
8055276479Sdim    }
8056276479Sdim
8057276479Sdim    // OpenMP [2.14.4.2, Restrictions, p.2]
8058276479Sdim    //  A list item that appears in a copyprivate clause may not appear in a
8059276479Sdim    //  private or firstprivate clause on the single construct.
8060276479Sdim    if (!DSAStack->isThreadPrivate(VD)) {
8061276479Sdim      auto DVar = DSAStack->getTopDSA(VD, false);
8062288943Sdim      if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
8063288943Sdim          DVar.RefExpr) {
8064276479Sdim        Diag(ELoc, diag::err_omp_wrong_dsa)
8065276479Sdim            << getOpenMPClauseName(DVar.CKind)
8066276479Sdim            << getOpenMPClauseName(OMPC_copyprivate);
8067276479Sdim        ReportOriginalDSA(*this, DSAStack, VD, DVar);
8068276479Sdim        continue;
8069276479Sdim      }
8070276479Sdim
8071276479Sdim      // OpenMP [2.11.4.2, Restrictions, p.1]
8072276479Sdim      //  All list items that appear in a copyprivate clause must be either
8073276479Sdim      //  threadprivate or private in the enclosing context.
8074276479Sdim      if (DVar.CKind == OMPC_unknown) {
8075276479Sdim        DVar = DSAStack->getImplicitDSA(VD, false);
8076276479Sdim        if (DVar.CKind == OMPC_shared) {
8077276479Sdim          Diag(ELoc, diag::err_omp_required_access)
8078276479Sdim              << getOpenMPClauseName(OMPC_copyprivate)
8079276479Sdim              << "threadprivate or private in the enclosing context";
8080276479Sdim          ReportOriginalDSA(*this, DSAStack, VD, DVar);
8081276479Sdim          continue;
8082276479Sdim        }
8083276479Sdim      }
8084276479Sdim    }
8085276479Sdim
8086288943Sdim    // Variably modified types are not supported.
8087288943Sdim    if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
8088288943Sdim      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
8089288943Sdim          << getOpenMPClauseName(OMPC_copyprivate) << Type
8090288943Sdim          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
8091288943Sdim      bool IsDecl =
8092288943Sdim          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
8093288943Sdim      Diag(VD->getLocation(),
8094288943Sdim           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
8095288943Sdim          << VD;
8096288943Sdim      continue;
8097288943Sdim    }
8098288943Sdim
8099276479Sdim    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
8100276479Sdim    //  A variable of class type (or array thereof) that appears in a
8101276479Sdim    //  copyin clause requires an accessible, unambiguous copy assignment
8102276479Sdim    //  operator for the class type.
8103296417Sdim    Type = Context.getBaseElementType(Type.getNonReferenceType())
8104296417Sdim               .getUnqualifiedType();
8105288943Sdim    auto *SrcVD =
8106296417Sdim        buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src",
8107296417Sdim                     VD->hasAttrs() ? &VD->getAttrs() : nullptr);
8108288943Sdim    auto *PseudoSrcExpr =
8109288943Sdim        buildDeclRefExpr(*this, SrcVD, Type, DE->getExprLoc());
8110288943Sdim    auto *DstVD =
8111296417Sdim        buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst",
8112296417Sdim                     VD->hasAttrs() ? &VD->getAttrs() : nullptr);
8113288943Sdim    auto *PseudoDstExpr =
8114288943Sdim        buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
8115288943Sdim    auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
8116288943Sdim                                   PseudoDstExpr, PseudoSrcExpr);
8117288943Sdim    if (AssignmentOp.isInvalid())
8118288943Sdim      continue;
8119288943Sdim    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
8120288943Sdim                                       /*DiscardedValue=*/true);
8121288943Sdim    if (AssignmentOp.isInvalid())
8122288943Sdim      continue;
8123276479Sdim
8124276479Sdim    // No need to mark vars as copyprivate, they are already threadprivate or
8125276479Sdim    // implicitly private.
8126276479Sdim    Vars.push_back(DE);
8127288943Sdim    SrcExprs.push_back(PseudoSrcExpr);
8128288943Sdim    DstExprs.push_back(PseudoDstExpr);
8129288943Sdim    AssignmentOps.push_back(AssignmentOp.get());
8130276479Sdim  }
8131276479Sdim
8132276479Sdim  if (Vars.empty())
8133276479Sdim    return nullptr;
8134276479Sdim
8135288943Sdim  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
8136288943Sdim                                      Vars, SrcExprs, DstExprs, AssignmentOps);
8137276479Sdim}
8138276479Sdim
8139276479SdimOMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
8140276479Sdim                                        SourceLocation StartLoc,
8141276479Sdim                                        SourceLocation LParenLoc,
8142276479Sdim                                        SourceLocation EndLoc) {
8143276479Sdim  if (VarList.empty())
8144276479Sdim    return nullptr;
8145276479Sdim
8146276479Sdim  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
8147276479Sdim}
8148276479Sdim
8149288943SdimOMPClause *
8150288943SdimSema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
8151288943Sdim                              SourceLocation DepLoc, SourceLocation ColonLoc,
8152288943Sdim                              ArrayRef<Expr *> VarList, SourceLocation StartLoc,
8153288943Sdim                              SourceLocation LParenLoc, SourceLocation EndLoc) {
8154296417Sdim  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
8155296417Sdim      DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
8156296417Sdim    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
8157296417Sdim        << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
8158296417Sdim    return nullptr;
8159296417Sdim  }
8160296417Sdim  if (DSAStack->getCurrentDirective() != OMPD_ordered &&
8161296417Sdim      (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
8162296417Sdim       DepKind == OMPC_DEPEND_sink)) {
8163296417Sdim    unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
8164296417Sdim    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
8165296417Sdim        << getListOfPossibleValues(OMPC_depend, /*First=*/0,
8166296417Sdim                                   /*Last=*/OMPC_DEPEND_unknown, Except)
8167296417Sdim        << getOpenMPClauseName(OMPC_depend);
8168296417Sdim    return nullptr;
8169296417Sdim  }
8170296417Sdim  SmallVector<Expr *, 8> Vars;
8171296417Sdim  llvm::APSInt DepCounter(/*BitWidth=*/32);
8172296417Sdim  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
8173296417Sdim  if (DepKind == OMPC_DEPEND_sink) {
8174296417Sdim    if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) {
8175296417Sdim      TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
8176296417Sdim      TotalDepCount.setIsUnsigned(/*Val=*/true);
8177296417Sdim    }
8178296417Sdim  }
8179296417Sdim  if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
8180296417Sdim      DSAStack->getParentOrderedRegionParam()) {
8181296417Sdim    for (auto &RefExpr : VarList) {
8182296417Sdim      assert(RefExpr && "NULL expr in OpenMP shared clause.");
8183296417Sdim      if (isa<DependentScopeDeclRefExpr>(RefExpr) ||
8184296417Sdim          (DepKind == OMPC_DEPEND_sink && CurContext->isDependentContext())) {
8185296417Sdim        // It will be analyzed later.
8186296417Sdim        Vars.push_back(RefExpr);
8187296417Sdim        continue;
8188288943Sdim      }
8189296417Sdim
8190296417Sdim      SourceLocation ELoc = RefExpr->getExprLoc();
8191296417Sdim      auto *SimpleExpr = RefExpr->IgnoreParenCasts();
8192296417Sdim      if (DepKind == OMPC_DEPEND_sink) {
8193296417Sdim        if (DepCounter >= TotalDepCount) {
8194296417Sdim          Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
8195296417Sdim          continue;
8196296417Sdim        }
8197296417Sdim        ++DepCounter;
8198296417Sdim        // OpenMP  [2.13.9, Summary]
8199296417Sdim        // depend(dependence-type : vec), where dependence-type is:
8200296417Sdim        // 'sink' and where vec is the iteration vector, which has the form:
8201296417Sdim        //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
8202296417Sdim        // where n is the value specified by the ordered clause in the loop
8203296417Sdim        // directive, xi denotes the loop iteration variable of the i-th nested
8204296417Sdim        // loop associated with the loop directive, and di is a constant
8205296417Sdim        // non-negative integer.
8206296417Sdim        SimpleExpr = SimpleExpr->IgnoreImplicit();
8207296417Sdim        auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
8208296417Sdim        if (!DE) {
8209296417Sdim          OverloadedOperatorKind OOK = OO_None;
8210296417Sdim          SourceLocation OOLoc;
8211296417Sdim          Expr *LHS, *RHS;
8212296417Sdim          if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
8213296417Sdim            OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
8214296417Sdim            OOLoc = BO->getOperatorLoc();
8215296417Sdim            LHS = BO->getLHS()->IgnoreParenImpCasts();
8216296417Sdim            RHS = BO->getRHS()->IgnoreParenImpCasts();
8217296417Sdim          } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
8218296417Sdim            OOK = OCE->getOperator();
8219296417Sdim            OOLoc = OCE->getOperatorLoc();
8220296417Sdim            LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
8221296417Sdim            RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
8222296417Sdim          } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
8223296417Sdim            OOK = MCE->getMethodDecl()
8224296417Sdim                      ->getNameInfo()
8225296417Sdim                      .getName()
8226296417Sdim                      .getCXXOverloadedOperator();
8227296417Sdim            OOLoc = MCE->getCallee()->getExprLoc();
8228296417Sdim            LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
8229296417Sdim            RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
8230296417Sdim          } else {
8231296417Sdim            Diag(ELoc, diag::err_omp_depend_sink_wrong_expr);
8232296417Sdim            continue;
8233296417Sdim          }
8234296417Sdim          DE = dyn_cast<DeclRefExpr>(LHS);
8235296417Sdim          if (!DE) {
8236296417Sdim            Diag(LHS->getExprLoc(),
8237296417Sdim                 diag::err_omp_depend_sink_expected_loop_iteration)
8238296417Sdim                << DSAStack->getParentLoopControlVariable(
8239296417Sdim                    DepCounter.getZExtValue());
8240296417Sdim            continue;
8241296417Sdim          }
8242296417Sdim          if (OOK != OO_Plus && OOK != OO_Minus) {
8243296417Sdim            Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
8244296417Sdim            continue;
8245296417Sdim          }
8246296417Sdim          ExprResult Res = VerifyPositiveIntegerConstantInClause(
8247296417Sdim              RHS, OMPC_depend, /*StrictlyPositive=*/false);
8248296417Sdim          if (Res.isInvalid())
8249296417Sdim            continue;
8250296417Sdim        }
8251296417Sdim        auto *VD = dyn_cast<VarDecl>(DE->getDecl());
8252296417Sdim        if (!CurContext->isDependentContext() &&
8253296417Sdim            DSAStack->getParentOrderedRegionParam() &&
8254296417Sdim            (!VD || DepCounter != DSAStack->isParentLoopControlVariable(VD))) {
8255296417Sdim          Diag(DE->getExprLoc(),
8256296417Sdim               diag::err_omp_depend_sink_expected_loop_iteration)
8257296417Sdim              << DSAStack->getParentLoopControlVariable(
8258296417Sdim                  DepCounter.getZExtValue());
8259296417Sdim          continue;
8260296417Sdim        }
8261296417Sdim      } else {
8262296417Sdim        // OpenMP  [2.11.1.1, Restrictions, p.3]
8263296417Sdim        //  A variable that is part of another variable (such as a field of a
8264296417Sdim        //  structure) but is not an array element or an array section cannot
8265296417Sdim        //  appear  in a depend clause.
8266296417Sdim        auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
8267296417Sdim        auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
8268296417Sdim        auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
8269296417Sdim        if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
8270296417Sdim            (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) ||
8271296417Sdim            (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
8272296417Sdim             !ASE->getBase()->getType()->isArrayType())) {
8273296417Sdim          Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
8274296417Sdim              << RefExpr->getSourceRange();
8275296417Sdim          continue;
8276296417Sdim        }
8277296417Sdim      }
8278296417Sdim
8279296417Sdim      Vars.push_back(RefExpr->IgnoreParenImpCasts());
8280288943Sdim    }
8281296417Sdim
8282296417Sdim    if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
8283296417Sdim        TotalDepCount > VarList.size() &&
8284296417Sdim        DSAStack->getParentOrderedRegionParam()) {
8285296417Sdim      Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
8286296417Sdim          << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
8287296417Sdim    }
8288296417Sdim    if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
8289296417Sdim        Vars.empty())
8290296417Sdim      return nullptr;
8291296417Sdim  }
8292296417Sdim
8293296417Sdim  return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind,
8294296417Sdim                                 DepLoc, ColonLoc, Vars);
8295296417Sdim}
8296296417Sdim
8297296417SdimOMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
8298296417Sdim                                         SourceLocation LParenLoc,
8299296417Sdim                                         SourceLocation EndLoc) {
8300296417Sdim  Expr *ValExpr = Device;
8301296417Sdim
8302296417Sdim  // OpenMP [2.9.1, Restrictions]
8303296417Sdim  // The device expression must evaluate to a non-negative integer value.
8304296417Sdim  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
8305296417Sdim                                 /*StrictlyPositive=*/false))
8306288943Sdim    return nullptr;
8307296417Sdim
8308296417Sdim  return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8309296417Sdim}
8310296417Sdim
8311296417Sdimstatic bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc,
8312296417Sdim                                   DSAStackTy *Stack, CXXRecordDecl *RD) {
8313296417Sdim  if (!RD || RD->isInvalidDecl())
8314296417Sdim    return true;
8315296417Sdim
8316296417Sdim  if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
8317296417Sdim    if (auto *CTD = CTSD->getSpecializedTemplate())
8318296417Sdim      RD = CTD->getTemplatedDecl();
8319296417Sdim  auto QTy = SemaRef.Context.getRecordType(RD);
8320296417Sdim  if (RD->isDynamicClass()) {
8321296417Sdim    SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
8322296417Sdim    SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target);
8323296417Sdim    return false;
8324288943Sdim  }
8325296417Sdim  auto *DC = RD;
8326296417Sdim  bool IsCorrect = true;
8327296417Sdim  for (auto *I : DC->decls()) {
8328296417Sdim    if (I) {
8329296417Sdim      if (auto *MD = dyn_cast<CXXMethodDecl>(I)) {
8330296417Sdim        if (MD->isStatic()) {
8331296417Sdim          SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
8332296417Sdim          SemaRef.Diag(MD->getLocation(),
8333296417Sdim                       diag::note_omp_static_member_in_target);
8334296417Sdim          IsCorrect = false;
8335296417Sdim        }
8336296417Sdim      } else if (auto *VD = dyn_cast<VarDecl>(I)) {
8337296417Sdim        if (VD->isStaticDataMember()) {
8338296417Sdim          SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
8339296417Sdim          SemaRef.Diag(VD->getLocation(),
8340296417Sdim                       diag::note_omp_static_member_in_target);
8341296417Sdim          IsCorrect = false;
8342296417Sdim        }
8343296417Sdim      }
8344296417Sdim    }
8345296417Sdim  }
8346296417Sdim
8347296417Sdim  for (auto &I : RD->bases()) {
8348296417Sdim    if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack,
8349296417Sdim                                I.getType()->getAsCXXRecordDecl()))
8350296417Sdim      IsCorrect = false;
8351296417Sdim  }
8352296417Sdim  return IsCorrect;
8353296417Sdim}
8354296417Sdim
8355296417Sdimstatic bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
8356296417Sdim                              DSAStackTy *Stack, QualType QTy) {
8357296417Sdim  NamedDecl *ND;
8358296417Sdim  if (QTy->isIncompleteType(&ND)) {
8359296417Sdim    SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
8360296417Sdim    return false;
8361296417Sdim  } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) {
8362296417Sdim    if (!RD->isInvalidDecl() &&
8363296417Sdim        !IsCXXRecordForMappable(SemaRef, SL, Stack, RD))
8364296417Sdim      return false;
8365296417Sdim  }
8366296417Sdim  return true;
8367296417Sdim}
8368296417Sdim
8369296417SdimOMPClause *Sema::ActOnOpenMPMapClause(
8370296417Sdim    OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType,
8371296417Sdim    SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
8372296417Sdim    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
8373296417Sdim  SmallVector<Expr *, 4> Vars;
8374296417Sdim
8375296417Sdim  for (auto &RE : VarList) {
8376296417Sdim    assert(RE && "Null expr in omp map");
8377296417Sdim    if (isa<DependentScopeDeclRefExpr>(RE)) {
8378288943Sdim      // It will be analyzed later.
8379296417Sdim      Vars.push_back(RE);
8380288943Sdim      continue;
8381288943Sdim    }
8382296417Sdim    SourceLocation ELoc = RE->getExprLoc();
8383288943Sdim
8384296417Sdim    // OpenMP [2.14.5, Restrictions]
8385296417Sdim    //  A variable that is part of another variable (such as field of a
8386288943Sdim    //  structure) but is not an array element or an array section cannot appear
8387296417Sdim    //  in a map clause.
8388296417Sdim    auto *VE = RE->IgnoreParenLValueCasts();
8389296417Sdim
8390296417Sdim    if (VE->isValueDependent() || VE->isTypeDependent() ||
8391296417Sdim        VE->isInstantiationDependent() ||
8392296417Sdim        VE->containsUnexpandedParameterPack()) {
8393296417Sdim      // It will be analyzed later.
8394296417Sdim      Vars.push_back(RE);
8395296417Sdim      continue;
8396296417Sdim    }
8397296417Sdim
8398296417Sdim    auto *SimpleExpr = RE->IgnoreParenCasts();
8399296417Sdim    auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
8400296417Sdim    auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
8401296417Sdim    auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
8402296417Sdim
8403296417Sdim    if (!RE->IgnoreParenImpCasts()->isLValue() ||
8404296417Sdim        (!OASE && !ASE && !DE) ||
8405288943Sdim        (DE && !isa<VarDecl>(DE->getDecl())) ||
8406288943Sdim        (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
8407288943Sdim         !ASE->getBase()->getType()->isArrayType())) {
8408288943Sdim      Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
8409296417Sdim        << RE->getSourceRange();
8410288943Sdim      continue;
8411288943Sdim    }
8412288943Sdim
8413296417Sdim    Decl *D = nullptr;
8414296417Sdim    if (DE) {
8415296417Sdim      D = DE->getDecl();
8416296417Sdim    } else if (ASE) {
8417296417Sdim      auto *B = ASE->getBase()->IgnoreParenCasts();
8418296417Sdim      D = dyn_cast<DeclRefExpr>(B)->getDecl();
8419296417Sdim    } else if (OASE) {
8420296417Sdim      auto *B = OASE->getBase();
8421296417Sdim      D = dyn_cast<DeclRefExpr>(B)->getDecl();
8422296417Sdim    }
8423296417Sdim    assert(D && "Null decl on map clause.");
8424296417Sdim    auto *VD = cast<VarDecl>(D);
8425296417Sdim
8426296417Sdim    // OpenMP [2.14.5, Restrictions, p.8]
8427296417Sdim    // threadprivate variables cannot appear in a map clause.
8428296417Sdim    if (DSAStack->isThreadPrivate(VD)) {
8429296417Sdim      auto DVar = DSAStack->getTopDSA(VD, false);
8430296417Sdim      Diag(ELoc, diag::err_omp_threadprivate_in_map);
8431296417Sdim      ReportOriginalDSA(*this, DSAStack, VD, DVar);
8432296417Sdim      continue;
8433296417Sdim    }
8434296417Sdim
8435296417Sdim    // OpenMP [2.14.5, Restrictions, p.2]
8436296417Sdim    //  At most one list item can be an array item derived from a given variable
8437296417Sdim    //  in map clauses of the same construct.
8438296417Sdim    // OpenMP [2.14.5, Restrictions, p.3]
8439296417Sdim    //  List items of map clauses in the same construct must not share original
8440296417Sdim    //  storage.
8441296417Sdim    // OpenMP [2.14.5, Restrictions, C/C++, p.2]
8442296417Sdim    //  A variable for which the type is pointer, reference to array, or
8443296417Sdim    //  reference to pointer and an array section derived from that variable
8444296417Sdim    //  must not appear as list items of map clauses of the same construct.
8445296417Sdim    DSAStackTy::MapInfo MI = DSAStack->IsMappedInCurrentRegion(VD);
8446296417Sdim    if (MI.RefExpr) {
8447296417Sdim      Diag(ELoc, diag::err_omp_map_shared_storage) << ELoc;
8448296417Sdim      Diag(MI.RefExpr->getExprLoc(), diag::note_used_here)
8449296417Sdim          << MI.RefExpr->getSourceRange();
8450296417Sdim      continue;
8451296417Sdim    }
8452296417Sdim
8453296417Sdim    // OpenMP [2.14.5, Restrictions, C/C++, p.3,4]
8454296417Sdim    //  A variable for which the type is pointer, reference to array, or
8455296417Sdim    //  reference to pointer must not appear as a list item if the enclosing
8456296417Sdim    //  device data environment already contains an array section derived from
8457296417Sdim    //  that variable.
8458296417Sdim    //  An array section derived from a variable for which the type is pointer,
8459296417Sdim    //  reference to array, or reference to pointer must not appear as a list
8460296417Sdim    //  item if the enclosing device data environment already contains that
8461296417Sdim    //  variable.
8462296417Sdim    QualType Type = VD->getType();
8463296417Sdim    MI = DSAStack->getMapInfoForVar(VD);
8464296417Sdim    if (MI.RefExpr && (isa<DeclRefExpr>(MI.RefExpr->IgnoreParenLValueCasts()) !=
8465296417Sdim                       isa<DeclRefExpr>(VE)) &&
8466296417Sdim        (Type->isPointerType() || Type->isReferenceType())) {
8467296417Sdim      Diag(ELoc, diag::err_omp_map_shared_storage) << ELoc;
8468296417Sdim      Diag(MI.RefExpr->getExprLoc(), diag::note_used_here)
8469296417Sdim          << MI.RefExpr->getSourceRange();
8470296417Sdim      continue;
8471296417Sdim    }
8472296417Sdim
8473296417Sdim    // OpenMP [2.14.5, Restrictions, C/C++, p.7]
8474296417Sdim    //  A list item must have a mappable type.
8475296417Sdim    if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), *this,
8476296417Sdim                           DSAStack, Type))
8477296417Sdim      continue;
8478296417Sdim
8479296417Sdim    Vars.push_back(RE);
8480296417Sdim    MI.RefExpr = RE;
8481296417Sdim    DSAStack->addMapInfoForVar(VD, MI);
8482288943Sdim  }
8483288943Sdim  if (Vars.empty())
8484288943Sdim    return nullptr;
8485288943Sdim
8486296417Sdim  return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
8487296417Sdim                              MapTypeModifier, MapType, MapLoc);
8488288943Sdim}
8489288943Sdim
8490296417SdimOMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
8491296417Sdim                                           SourceLocation StartLoc,
8492296417Sdim                                           SourceLocation LParenLoc,
8493296417Sdim                                           SourceLocation EndLoc) {
8494296417Sdim  Expr *ValExpr = NumTeams;
8495296417Sdim
8496296417Sdim  // OpenMP [teams Constrcut, Restrictions]
8497296417Sdim  // The num_teams expression must evaluate to a positive integer value.
8498296417Sdim  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
8499296417Sdim                                 /*StrictlyPositive=*/true))
8500296417Sdim    return nullptr;
8501296417Sdim
8502296417Sdim  return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8503296417Sdim}
8504296417Sdim
8505296417SdimOMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
8506296417Sdim                                              SourceLocation StartLoc,
8507296417Sdim                                              SourceLocation LParenLoc,
8508296417Sdim                                              SourceLocation EndLoc) {
8509296417Sdim  Expr *ValExpr = ThreadLimit;
8510296417Sdim
8511296417Sdim  // OpenMP [teams Constrcut, Restrictions]
8512296417Sdim  // The thread_limit expression must evaluate to a positive integer value.
8513296417Sdim  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
8514296417Sdim                                 /*StrictlyPositive=*/true))
8515296417Sdim    return nullptr;
8516296417Sdim
8517296417Sdim  return new (Context) OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc,
8518296417Sdim                                            EndLoc);
8519296417Sdim}
8520296417Sdim
8521296417SdimOMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
8522296417Sdim                                           SourceLocation StartLoc,
8523296417Sdim                                           SourceLocation LParenLoc,
8524296417Sdim                                           SourceLocation EndLoc) {
8525296417Sdim  Expr *ValExpr = Priority;
8526296417Sdim
8527296417Sdim  // OpenMP [2.9.1, task Constrcut]
8528296417Sdim  // The priority-value is a non-negative numerical scalar expression.
8529296417Sdim  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
8530296417Sdim                                 /*StrictlyPositive=*/false))
8531296417Sdim    return nullptr;
8532296417Sdim
8533296417Sdim  return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8534296417Sdim}
8535296417Sdim
8536296417SdimOMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
8537296417Sdim                                            SourceLocation StartLoc,
8538296417Sdim                                            SourceLocation LParenLoc,
8539296417Sdim                                            SourceLocation EndLoc) {
8540296417Sdim  Expr *ValExpr = Grainsize;
8541296417Sdim
8542296417Sdim  // OpenMP [2.9.2, taskloop Constrcut]
8543296417Sdim  // The parameter of the grainsize clause must be a positive integer
8544296417Sdim  // expression.
8545296417Sdim  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
8546296417Sdim                                 /*StrictlyPositive=*/true))
8547296417Sdim    return nullptr;
8548296417Sdim
8549296417Sdim  return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8550296417Sdim}
8551296417Sdim
8552296417SdimOMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
8553296417Sdim                                           SourceLocation StartLoc,
8554296417Sdim                                           SourceLocation LParenLoc,
8555296417Sdim                                           SourceLocation EndLoc) {
8556296417Sdim  Expr *ValExpr = NumTasks;
8557296417Sdim
8558296417Sdim  // OpenMP [2.9.2, taskloop Constrcut]
8559296417Sdim  // The parameter of the num_tasks clause must be a positive integer
8560296417Sdim  // expression.
8561296417Sdim  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
8562296417Sdim                                 /*StrictlyPositive=*/true))
8563296417Sdim    return nullptr;
8564296417Sdim
8565296417Sdim  return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8566296417Sdim}
8567296417Sdim
8568296417SdimOMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
8569296417Sdim                                       SourceLocation LParenLoc,
8570296417Sdim                                       SourceLocation EndLoc) {
8571296417Sdim  // OpenMP [2.13.2, critical construct, Description]
8572296417Sdim  // ... where hint-expression is an integer constant expression that evaluates
8573296417Sdim  // to a valid lock hint.
8574296417Sdim  ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
8575296417Sdim  if (HintExpr.isInvalid())
8576296417Sdim    return nullptr;
8577296417Sdim  return new (Context)
8578296417Sdim      OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
8579296417Sdim}
8580296417Sdim
8581