clang  3.8.0
SemaOpenMP.cpp
Go to the documentation of this file.
1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// \brief This file implements semantic analysis for OpenMP directives and
11 /// clauses.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "TreeTransform.h"
16 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/StmtCXX.h"
22 #include "clang/AST/StmtOpenMP.h"
23 #include "clang/AST/StmtVisitor.h"
25 #include "clang/Basic/TargetInfo.h"
26 #include "clang/Lex/Preprocessor.h"
28 #include "clang/Sema/Lookup.h"
29 #include "clang/Sema/Scope.h"
30 #include "clang/Sema/ScopeInfo.h"
32 using namespace clang;
33 
34 //===----------------------------------------------------------------------===//
35 // Stack of data-sharing attributes for variables
36 //===----------------------------------------------------------------------===//
37 
38 namespace {
39 /// \brief Default data sharing attributes, which can be applied to directive.
41  DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
42  DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'.
43  DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'.
44 };
45 
46 template <class T> struct MatchesAny {
47  explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {}
48  bool operator()(T Kind) {
49  for (auto KindEl : Arr)
50  if (KindEl == Kind)
51  return true;
52  return false;
53  }
54 
55 private:
56  ArrayRef<T> Arr;
57 };
58 struct MatchesAlways {
59  MatchesAlways() {}
60  template <class T> bool operator()(T) { return true; }
61 };
62 
63 typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause;
64 typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective;
65 
66 /// \brief Stack for tracking declarations used in OpenMP directives and
67 /// clauses and their data-sharing attributes.
68 class DSAStackTy {
69 public:
70  struct DSAVarData {
71  OpenMPDirectiveKind DKind;
72  OpenMPClauseKind CKind;
73  DeclRefExpr *RefExpr;
74  SourceLocation ImplicitDSALoc;
75  DSAVarData()
76  : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr),
77  ImplicitDSALoc() {}
78  };
79 
80 public:
81  struct MapInfo {
82  Expr *RefExpr;
83  };
84 
85 private:
86  struct DSAInfo {
87  OpenMPClauseKind Attributes;
88  DeclRefExpr *RefExpr;
89  };
90  typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
91  typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
92  typedef llvm::DenseMap<VarDecl *, unsigned> LoopControlVariablesMapTy;
93  typedef llvm::SmallDenseMap<VarDecl *, MapInfo, 64> MappedDeclsTy;
94  typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
95  CriticalsWithHintsTy;
96 
97  struct SharingMapTy {
98  DeclSAMapTy SharingMap;
99  AlignedMapTy AlignedMap;
100  MappedDeclsTy MappedDecls;
101  LoopControlVariablesMapTy LCVMap;
102  DefaultDataSharingAttributes DefaultAttr;
103  SourceLocation DefaultAttrLoc;
105  DeclarationNameInfo DirectiveName;
106  Scope *CurScope;
107  SourceLocation ConstructLoc;
108  /// \brief first argument (Expr *) contains optional argument of the
109  /// 'ordered' clause, the second one is true if the regions has 'ordered'
110  /// clause, false otherwise.
111  llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
112  bool NowaitRegion;
113  bool CancelRegion;
114  unsigned AssociatedLoops;
115  SourceLocation InnerTeamsRegionLoc;
116  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
117  Scope *CurScope, SourceLocation Loc)
118  : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified),
119  Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
120  ConstructLoc(Loc), OrderedRegion(), NowaitRegion(false),
121  CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {}
122  SharingMapTy()
123  : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified),
124  Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
125  ConstructLoc(), OrderedRegion(), NowaitRegion(false),
126  CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {}
127  };
128 
129  typedef SmallVector<SharingMapTy, 64> StackTy;
130 
131  /// \brief Stack of used declaration and their data-sharing attributes.
132  StackTy Stack;
133  /// \brief true, if check for DSA must be from parent directive, false, if
134  /// from current directive.
135  OpenMPClauseKind ClauseKindMode;
136  Sema &SemaRef;
137  bool ForceCapturing;
138  CriticalsWithHintsTy Criticals;
139 
140  typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
141 
142  DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D);
143 
144  /// \brief Checks if the variable is a local for OpenMP region.
145  bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
146 
147 public:
148  explicit DSAStackTy(Sema &S)
149  : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S),
150  ForceCapturing(false) {}
151 
152  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
153  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
154 
155  bool isForceVarCapturing() const { return ForceCapturing; }
156  void setForceVarCapturing(bool V) { ForceCapturing = V; }
157 
158  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
159  Scope *CurScope, SourceLocation Loc) {
160  Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
161  Stack.back().DefaultAttrLoc = Loc;
162  }
163 
164  void pop() {
165  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!");
166  Stack.pop_back();
167  }
168 
169  void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) {
170  Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint);
171  }
172  const std::pair<OMPCriticalDirective *, llvm::APSInt>
173  getCriticalWithHint(const DeclarationNameInfo &Name) const {
174  auto I = Criticals.find(Name.getAsString());
175  if (I != Criticals.end())
176  return I->second;
177  return std::make_pair(nullptr, llvm::APSInt());
178  }
179  /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
180  /// add it and return NULL; otherwise return previous occurrence's expression
181  /// for diagnostics.
182  DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE);
183 
184  /// \brief Register specified variable as loop control variable.
185  void addLoopControlVariable(VarDecl *D);
186  /// \brief Check if the specified variable is a loop control variable for
187  /// current region.
188  /// \return The index of the loop control variable in the list of associated
189  /// for-loops (from outer to inner).
190  unsigned isLoopControlVariable(VarDecl *D);
191  /// \brief Check if the specified variable is a loop control variable for
192  /// parent region.
193  /// \return The index of the loop control variable in the list of associated
194  /// for-loops (from outer to inner).
195  unsigned isParentLoopControlVariable(VarDecl *D);
196  /// \brief Get the loop control variable for the I-th loop (or nullptr) in
197  /// parent directive.
198  VarDecl *getParentLoopControlVariable(unsigned I);
199 
200  /// \brief Adds explicit data sharing attribute to the specified declaration.
201  void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
202 
203  /// \brief Returns data sharing attributes from top of the stack for the
204  /// specified declaration.
205  DSAVarData getTopDSA(VarDecl *D, bool FromParent);
206  /// \brief Returns data-sharing attributes for the specified declaration.
207  DSAVarData getImplicitDSA(VarDecl *D, bool FromParent);
208  /// \brief Checks if the specified variables has data-sharing attributes which
209  /// match specified \a CPred predicate in any directive which matches \a DPred
210  /// predicate.
211  template <class ClausesPredicate, class DirectivesPredicate>
212  DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred,
213  DirectivesPredicate DPred, bool FromParent);
214  /// \brief Checks if the specified variables has data-sharing attributes which
215  /// match specified \a CPred predicate in any innermost directive which
216  /// matches \a DPred predicate.
217  template <class ClausesPredicate, class DirectivesPredicate>
218  DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
219  DirectivesPredicate DPred,
220  bool FromParent);
221  /// \brief Checks if the specified variables has explicit data-sharing
222  /// attributes which match specified \a CPred predicate at the specified
223  /// OpenMP region.
224  bool hasExplicitDSA(VarDecl *D,
225  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
226  unsigned Level);
227 
228  /// \brief Returns true if the directive at level \Level matches in the
229  /// specified \a DPred predicate.
230  bool hasExplicitDirective(
231  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
232  unsigned Level);
233 
234  /// \brief Finds a directive which matches specified \a DPred predicate.
235  template <class NamedDirectivesPredicate>
236  bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent);
237 
238  /// \brief Returns currently analyzed directive.
239  OpenMPDirectiveKind getCurrentDirective() const {
240  return Stack.back().Directive;
241  }
242  /// \brief Returns parent directive.
243  OpenMPDirectiveKind getParentDirective() const {
244  if (Stack.size() > 2)
245  return Stack[Stack.size() - 2].Directive;
246  return OMPD_unknown;
247  }
248  /// \brief Return the directive associated with the provided scope.
249  OpenMPDirectiveKind getDirectiveForScope(const Scope *S) const;
250 
251  /// \brief Set default data sharing attribute to none.
252  void setDefaultDSANone(SourceLocation Loc) {
253  Stack.back().DefaultAttr = DSA_none;
254  Stack.back().DefaultAttrLoc = Loc;
255  }
256  /// \brief Set default data sharing attribute to shared.
257  void setDefaultDSAShared(SourceLocation Loc) {
258  Stack.back().DefaultAttr = DSA_shared;
259  Stack.back().DefaultAttrLoc = Loc;
260  }
261 
262  DefaultDataSharingAttributes getDefaultDSA() const {
263  return Stack.back().DefaultAttr;
264  }
265  SourceLocation getDefaultDSALocation() const {
266  return Stack.back().DefaultAttrLoc;
267  }
268 
269  /// \brief Checks if the specified variable is a threadprivate.
270  bool isThreadPrivate(VarDecl *D) {
271  DSAVarData DVar = getTopDSA(D, false);
272  return isOpenMPThreadPrivate(DVar.CKind);
273  }
274 
275  /// \brief Marks current region as ordered (it has an 'ordered' clause).
276  void setOrderedRegion(bool IsOrdered, Expr *Param) {
277  Stack.back().OrderedRegion.setInt(IsOrdered);
278  Stack.back().OrderedRegion.setPointer(Param);
279  }
280  /// \brief Returns true, if parent region is ordered (has associated
281  /// 'ordered' clause), false - otherwise.
282  bool isParentOrderedRegion() const {
283  if (Stack.size() > 2)
284  return Stack[Stack.size() - 2].OrderedRegion.getInt();
285  return false;
286  }
287  /// \brief Returns optional parameter for the ordered region.
288  Expr *getParentOrderedRegionParam() const {
289  if (Stack.size() > 2)
290  return Stack[Stack.size() - 2].OrderedRegion.getPointer();
291  return nullptr;
292  }
293  /// \brief Marks current region as nowait (it has a 'nowait' clause).
294  void setNowaitRegion(bool IsNowait = true) {
295  Stack.back().NowaitRegion = IsNowait;
296  }
297  /// \brief Returns true, if parent region is nowait (has associated
298  /// 'nowait' clause), false - otherwise.
299  bool isParentNowaitRegion() const {
300  if (Stack.size() > 2)
301  return Stack[Stack.size() - 2].NowaitRegion;
302  return false;
303  }
304  /// \brief Marks parent region as cancel region.
305  void setParentCancelRegion(bool Cancel = true) {
306  if (Stack.size() > 2)
307  Stack[Stack.size() - 2].CancelRegion =
308  Stack[Stack.size() - 2].CancelRegion || Cancel;
309  }
310  /// \brief Return true if current region has inner cancel construct.
311  bool isCancelRegion() const {
312  return Stack.back().CancelRegion;
313  }
314 
315  /// \brief Set collapse value for the region.
316  void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; }
317  /// \brief Return collapse value for region.
318  unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; }
319 
320  /// \brief Marks current target region as one with closely nested teams
321  /// region.
322  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
323  if (Stack.size() > 2)
324  Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc;
325  }
326  /// \brief Returns true, if current region has closely nested teams region.
327  bool hasInnerTeamsRegion() const {
328  return getInnerTeamsRegionLoc().isValid();
329  }
330  /// \brief Returns location of the nested teams region (if any).
331  SourceLocation getInnerTeamsRegionLoc() const {
332  if (Stack.size() > 1)
333  return Stack.back().InnerTeamsRegionLoc;
334  return SourceLocation();
335  }
336 
337  Scope *getCurScope() const { return Stack.back().CurScope; }
338  Scope *getCurScope() { return Stack.back().CurScope; }
339  SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
340 
341  MapInfo getMapInfoForVar(VarDecl *VD) {
342  MapInfo VarMI = {0};
343  for (auto Cnt = Stack.size() - 1; Cnt > 0; --Cnt) {
344  if (Stack[Cnt].MappedDecls.count(VD)) {
345  VarMI = Stack[Cnt].MappedDecls[VD];
346  break;
347  }
348  }
349  return VarMI;
350  }
351 
352  void addMapInfoForVar(VarDecl *VD, MapInfo MI) {
353  if (Stack.size() > 1) {
354  Stack.back().MappedDecls[VD] = MI;
355  }
356  }
357 
358  MapInfo IsMappedInCurrentRegion(VarDecl *VD) {
359  assert(Stack.size() > 1 && "Target level is 0");
360  MapInfo VarMI = {0};
361  if (Stack.size() > 1 && Stack.back().MappedDecls.count(VD)) {
362  VarMI = Stack.back().MappedDecls[VD];
363  }
364  return VarMI;
365  }
366 };
367 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
368  return isOpenMPParallelDirective(DKind) || DKind == OMPD_task ||
369  isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown ||
371 }
372 } // namespace
373 
374 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
375  VarDecl *D) {
376  D = D->getCanonicalDecl();
377  DSAVarData DVar;
378  if (Iter == std::prev(Stack.rend())) {
379  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
380  // in a region but not in construct]
381  // File-scope or namespace-scope variables referenced in called routines
382  // in the region are shared unless they appear in a threadprivate
383  // directive.
384  if (!D->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
385  DVar.CKind = OMPC_shared;
386 
387  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
388  // in a region but not in construct]
389  // Variables with static storage duration that are declared in called
390  // routines in the region are shared.
391  if (D->hasGlobalStorage())
392  DVar.CKind = OMPC_shared;
393 
394  return DVar;
395  }
396 
397  DVar.DKind = Iter->Directive;
398  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
399  // in a Construct, C/C++, predetermined, p.1]
400  // Variables with automatic storage duration that are declared in a scope
401  // inside the construct are private.
402  if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() &&
403  (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
404  DVar.CKind = OMPC_private;
405  return DVar;
406  }
407 
408  // Explicitly specified attributes and local variables with predetermined
409  // attributes.
410  if (Iter->SharingMap.count(D)) {
411  DVar.RefExpr = Iter->SharingMap[D].RefExpr;
412  DVar.CKind = Iter->SharingMap[D].Attributes;
413  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
414  return DVar;
415  }
416 
417  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
418  // in a Construct, C/C++, implicitly determined, p.1]
419  // In a parallel or task construct, the data-sharing attributes of these
420  // variables are determined by the default clause, if present.
421  switch (Iter->DefaultAttr) {
422  case DSA_shared:
423  DVar.CKind = OMPC_shared;
424  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
425  return DVar;
426  case DSA_none:
427  return DVar;
428  case DSA_unspecified:
429  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
430  // in a Construct, implicitly determined, p.2]
431  // In a parallel construct, if no default clause is present, these
432  // variables are shared.
433  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
434  if (isOpenMPParallelDirective(DVar.DKind) ||
435  isOpenMPTeamsDirective(DVar.DKind)) {
436  DVar.CKind = OMPC_shared;
437  return DVar;
438  }
439 
440  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
441  // in a Construct, implicitly determined, p.4]
442  // In a task construct, if no default clause is present, a variable that in
443  // the enclosing context is determined to be shared by all implicit tasks
444  // bound to the current team is shared.
445  if (DVar.DKind == OMPD_task) {
446  DSAVarData DVarTemp;
447  for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend();
448  I != EE; ++I) {
449  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
450  // Referenced
451  // in a Construct, implicitly determined, p.6]
452  // In a task construct, if no default clause is present, a variable
453  // whose data-sharing attribute is not determined by the rules above is
454  // firstprivate.
455  DVarTemp = getDSA(I, D);
456  if (DVarTemp.CKind != OMPC_shared) {
457  DVar.RefExpr = nullptr;
458  DVar.DKind = OMPD_task;
459  DVar.CKind = OMPC_firstprivate;
460  return DVar;
461  }
462  if (isParallelOrTaskRegion(I->Directive))
463  break;
464  }
465  DVar.DKind = OMPD_task;
466  DVar.CKind =
467  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
468  return DVar;
469  }
470  }
471  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
472  // in a Construct, implicitly determined, p.3]
473  // For constructs other than task, if no default clause is present, these
474  // variables inherit their data-sharing attributes from the enclosing
475  // context.
476  return getDSA(std::next(Iter), D);
477 }
478 
479 DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) {
480  assert(Stack.size() > 1 && "Data sharing attributes stack is empty");
481  D = D->getCanonicalDecl();
482  auto It = Stack.back().AlignedMap.find(D);
483  if (It == Stack.back().AlignedMap.end()) {
484  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
485  Stack.back().AlignedMap[D] = NewDE;
486  return nullptr;
487  } else {
488  assert(It->second && "Unexpected nullptr expr in the aligned map");
489  return It->second;
490  }
491  return nullptr;
492 }
493 
494 void DSAStackTy::addLoopControlVariable(VarDecl *D) {
495  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
496  D = D->getCanonicalDecl();
497  Stack.back().LCVMap.insert(std::make_pair(D, Stack.back().LCVMap.size() + 1));
498 }
499 
500 unsigned DSAStackTy::isLoopControlVariable(VarDecl *D) {
501  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
502  D = D->getCanonicalDecl();
503  return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] : 0;
504 }
505 
506 unsigned DSAStackTy::isParentLoopControlVariable(VarDecl *D) {
507  assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");
508  D = D->getCanonicalDecl();
509  return Stack[Stack.size() - 2].LCVMap.count(D) > 0
510  ? Stack[Stack.size() - 2].LCVMap[D]
511  : 0;
512 }
513 
514 VarDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) {
515  assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");
516  if (Stack[Stack.size() - 2].LCVMap.size() < I)
517  return nullptr;
518  for (auto &Pair : Stack[Stack.size() - 2].LCVMap) {
519  if (Pair.second == I)
520  return Pair.first;
521  }
522  return nullptr;
523 }
524 
525 void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
526  D = D->getCanonicalDecl();
527  if (A == OMPC_threadprivate) {
528  Stack[0].SharingMap[D].Attributes = A;
529  Stack[0].SharingMap[D].RefExpr = E;
530  } else {
531  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
532  Stack.back().SharingMap[D].Attributes = A;
533  Stack.back().SharingMap[D].RefExpr = E;
534  }
535 }
536 
537 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
538  D = D->getCanonicalDecl();
539  if (Stack.size() > 2) {
540  reverse_iterator I = Iter, E = std::prev(Stack.rend());
541  Scope *TopScope = nullptr;
542  while (I != E && !isParallelOrTaskRegion(I->Directive)) {
543  ++I;
544  }
545  if (I == E)
546  return false;
547  TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
548  Scope *CurScope = getCurScope();
549  while (CurScope != TopScope && !CurScope->isDeclScope(D)) {
550  CurScope = CurScope->getParent();
551  }
552  return CurScope != TopScope;
553  }
554  return false;
555 }
556 
557 /// \brief Build a variable declaration for OpenMP loop iteration variable.
559  StringRef Name, const AttrVec *Attrs = nullptr) {
560  DeclContext *DC = SemaRef.CurContext;
561  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
562  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
563  VarDecl *Decl =
564  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
565  if (Attrs) {
566  for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
567  I != E; ++I)
568  Decl->addAttr(*I);
569  }
570  Decl->setImplicit();
571  return Decl;
572 }
573 
575  SourceLocation Loc,
576  bool RefersToCapture = false) {
577  D->setReferenced();
578  D->markUsed(S.Context);
580  SourceLocation(), D, RefersToCapture, Loc, Ty,
581  VK_LValue);
582 }
583 
584 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
585  D = D->getCanonicalDecl();
586  DSAVarData DVar;
587 
588  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
589  // in a Construct, C/C++, predetermined, p.1]
590  // Variables appearing in threadprivate directives are threadprivate.
591  if ((D->getTLSKind() != VarDecl::TLS_None &&
592  !(D->hasAttr<OMPThreadPrivateDeclAttr>() &&
593  SemaRef.getLangOpts().OpenMPUseTLS &&
594  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
595  (D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() &&
596  !D->isLocalVarDecl())) {
597  addDSA(D, buildDeclRefExpr(SemaRef, D, D->getType().getNonReferenceType(),
598  D->getLocation()),
600  }
601  if (Stack[0].SharingMap.count(D)) {
602  DVar.RefExpr = Stack[0].SharingMap[D].RefExpr;
603  DVar.CKind = OMPC_threadprivate;
604  return DVar;
605  }
606 
607  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
608  // in a Construct, C/C++, predetermined, p.4]
609  // Static data members are shared.
610  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
611  // in a Construct, C/C++, predetermined, p.7]
612  // Variables with static storage duration that are declared in a scope
613  // inside the construct are shared.
614  if (D->isStaticDataMember()) {
615  DSAVarData DVarTemp =
616  hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent);
617  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
618  return DVar;
619 
620  DVar.CKind = OMPC_shared;
621  return DVar;
622  }
623 
625  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
626  Type = SemaRef.getASTContext().getBaseElementType(Type);
627  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
628  // in a Construct, C/C++, predetermined, p.6]
629  // Variables with const qualified type having no mutable member are
630  // shared.
631  CXXRecordDecl *RD =
632  SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
633  if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
634  if (auto *CTD = CTSD->getSpecializedTemplate())
635  RD = CTD->getTemplatedDecl();
636  if (IsConstant &&
637  !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
638  RD->hasMutableFields())) {
639  // Variables with const-qualified type having no mutable member may be
640  // listed in a firstprivate clause, even if they are static data members.
641  DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate),
642  MatchesAlways(), FromParent);
643  if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
644  return DVar;
645 
646  DVar.CKind = OMPC_shared;
647  return DVar;
648  }
649 
650  // Explicitly specified attributes and local variables with predetermined
651  // attributes.
652  auto StartI = std::next(Stack.rbegin());
653  auto EndI = std::prev(Stack.rend());
654  if (FromParent && StartI != EndI) {
655  StartI = std::next(StartI);
656  }
657  auto I = std::prev(StartI);
658  if (I->SharingMap.count(D)) {
659  DVar.RefExpr = I->SharingMap[D].RefExpr;
660  DVar.CKind = I->SharingMap[D].Attributes;
661  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
662  }
663 
664  return DVar;
665 }
666 
667 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D, bool FromParent) {
668  D = D->getCanonicalDecl();
669  auto StartI = Stack.rbegin();
670  auto EndI = std::prev(Stack.rend());
671  if (FromParent && StartI != EndI) {
672  StartI = std::next(StartI);
673  }
674  return getDSA(StartI, D);
675 }
676 
677 template <class ClausesPredicate, class DirectivesPredicate>
678 DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred,
679  DirectivesPredicate DPred,
680  bool FromParent) {
681  D = D->getCanonicalDecl();
682  auto StartI = std::next(Stack.rbegin());
683  auto EndI = std::prev(Stack.rend());
684  if (FromParent && StartI != EndI) {
685  StartI = std::next(StartI);
686  }
687  for (auto I = StartI, EE = EndI; I != EE; ++I) {
688  if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
689  continue;
690  DSAVarData DVar = getDSA(I, D);
691  if (CPred(DVar.CKind))
692  return DVar;
693  }
694  return DSAVarData();
695 }
696 
697 template <class ClausesPredicate, class DirectivesPredicate>
698 DSAStackTy::DSAVarData
699 DSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
700  DirectivesPredicate DPred, bool FromParent) {
701  D = D->getCanonicalDecl();
702  auto StartI = std::next(Stack.rbegin());
703  auto EndI = std::prev(Stack.rend());
704  if (FromParent && StartI != EndI) {
705  StartI = std::next(StartI);
706  }
707  for (auto I = StartI, EE = EndI; I != EE; ++I) {
708  if (!DPred(I->Directive))
709  break;
710  DSAVarData DVar = getDSA(I, D);
711  if (CPred(DVar.CKind))
712  return DVar;
713  return DSAVarData();
714  }
715  return DSAVarData();
716 }
717 
718 bool DSAStackTy::hasExplicitDSA(
719  VarDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
720  unsigned Level) {
721  if (CPred(ClauseKindMode))
722  return true;
723  if (isClauseParsingMode())
724  ++Level;
725  D = D->getCanonicalDecl();
726  auto StartI = Stack.rbegin();
727  auto EndI = std::prev(Stack.rend());
728  if (std::distance(StartI, EndI) <= (int)Level)
729  return false;
730  std::advance(StartI, Level);
731  return (StartI->SharingMap.count(D) > 0) && StartI->SharingMap[D].RefExpr &&
732  CPred(StartI->SharingMap[D].Attributes);
733 }
734 
735 bool DSAStackTy::hasExplicitDirective(
736  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
737  unsigned Level) {
738  if (isClauseParsingMode())
739  ++Level;
740  auto StartI = Stack.rbegin();
741  auto EndI = std::prev(Stack.rend());
742  if (std::distance(StartI, EndI) <= (int)Level)
743  return false;
744  std::advance(StartI, Level);
745  return DPred(StartI->Directive);
746 }
747 
748 template <class NamedDirectivesPredicate>
749 bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) {
750  auto StartI = std::next(Stack.rbegin());
751  auto EndI = std::prev(Stack.rend());
752  if (FromParent && StartI != EndI) {
753  StartI = std::next(StartI);
754  }
755  for (auto I = StartI, EE = EndI; I != EE; ++I) {
756  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
757  return true;
758  }
759  return false;
760 }
761 
762 OpenMPDirectiveKind DSAStackTy::getDirectiveForScope(const Scope *S) const {
763  for (auto I = Stack.rbegin(), EE = Stack.rend(); I != EE; ++I)
764  if (I->CurScope == S)
765  return I->Directive;
766  return OMPD_unknown;
767 }
768 
769 void Sema::InitDataSharingAttributesStack() {
770  VarDataSharingAttributesStack = new DSAStackTy(*this);
771 }
772 
773 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
774 
776  const CapturedRegionScopeInfo *RSI) {
777  assert(LangOpts.OpenMP && "OpenMP is not allowed");
778 
779  auto &Ctx = getASTContext();
780  bool IsByRef = true;
781 
782  // Find the directive that is associated with the provided scope.
783  auto DKind = DSAStack->getDirectiveForScope(RSI->TheScope);
784  auto Ty = VD->getType();
785 
786  if (isOpenMPTargetDirective(DKind)) {
787  // This table summarizes how a given variable should be passed to the device
788  // given its type and the clauses where it appears. This table is based on
789  // the description in OpenMP 4.5 [2.10.4, target Construct] and
790  // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
791  //
792  // =========================================================================
793  // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
794  // | |(tofrom:scalar)| | pvt | | | |
795  // =========================================================================
796  // | scl | | | | - | | bycopy|
797  // | scl | | - | x | - | - | bycopy|
798  // | scl | | x | - | - | - | null |
799  // | scl | x | | | - | | byref |
800  // | scl | x | - | x | - | - | bycopy|
801  // | scl | x | x | - | - | - | null |
802  // | scl | | - | - | - | x | byref |
803  // | scl | x | - | - | - | x | byref |
804  //
805  // | agg | n.a. | | | - | | byref |
806  // | agg | n.a. | - | x | - | - | byref |
807  // | agg | n.a. | x | - | - | - | null |
808  // | agg | n.a. | - | - | - | x | byref |
809  // | agg | n.a. | - | - | - | x[] | byref |
810  //
811  // | ptr | n.a. | | | - | | bycopy|
812  // | ptr | n.a. | - | x | - | - | bycopy|
813  // | ptr | n.a. | x | - | - | - | null |
814  // | ptr | n.a. | - | - | - | x | byref |
815  // | ptr | n.a. | - | - | - | x[] | bycopy|
816  // | ptr | n.a. | - | - | x | | bycopy|
817  // | ptr | n.a. | - | - | x | x | bycopy|
818  // | ptr | n.a. | - | - | x | x[] | bycopy|
819  // =========================================================================
820  // Legend:
821  // scl - scalar
822  // ptr - pointer
823  // agg - aggregate
824  // x - applies
825  // - - invalid in this combination
826  // [] - mapped with an array section
827  // byref - should be mapped by reference
828  // byval - should be mapped by value
829  // null - initialize a local variable to null on the device
830  //
831  // Observations:
832  // - All scalar declarations that show up in a map clause have to be passed
833  // by reference, because they may have been mapped in the enclosing data
834  // environment.
835  // - If the scalar value does not fit the size of uintptr, it has to be
836  // passed by reference, regardless the result in the table above.
837  // - For pointers mapped by value that have either an implicit map or an
838  // array section, the runtime library may pass the NULL value to the
839  // device instead of the value passed to it by the compiler.
840 
841  // FIXME: Right now, only implicit maps are implemented. Properly mapping
842  // values requires having the map, private, and firstprivate clauses SEMA
843  // and parsing in place, which we don't yet.
844 
845  if (Ty->isReferenceType())
846  Ty = Ty->castAs<ReferenceType>()->getPointeeType();
847  IsByRef = !Ty->isScalarType();
848  }
849 
850  // When passing data by value, we need to make sure it fits the uintptr size
851  // and alignment, because the runtime library only deals with uintptr types.
852  // If it does not fit the uintptr size, we need to pass the data by reference
853  // instead.
854  if (!IsByRef &&
855  (Ctx.getTypeSizeInChars(Ty) >
856  Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
857  Ctx.getDeclAlign(VD) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType())))
858  IsByRef = true;
859 
860  return IsByRef;
861 }
862 
864  assert(LangOpts.OpenMP && "OpenMP is not allowed");
865  VD = VD->getCanonicalDecl();
866 
867  // If we are attempting to capture a global variable in a directive with
868  // 'target' we return true so that this global is also mapped to the device.
869  //
870  // FIXME: If the declaration is enclosed in a 'declare target' directive,
871  // then it should not be captured. Therefore, an extra check has to be
872  // inserted here once support for 'declare target' is added.
873  //
874  if (!VD->hasLocalStorage()) {
875  if (DSAStack->getCurrentDirective() == OMPD_target &&
876  !DSAStack->isClauseParsingMode()) {
877  return true;
878  }
879  if (DSAStack->getCurScope() &&
880  DSAStack->hasDirective(
881  [](OpenMPDirectiveKind K, const DeclarationNameInfo &DNI,
882  SourceLocation Loc) -> bool {
883  return isOpenMPTargetDirective(K);
884  },
885  false)) {
886  return true;
887  }
888  }
889 
890  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
891  (!DSAStack->isClauseParsingMode() ||
892  DSAStack->getParentDirective() != OMPD_unknown)) {
893  if (DSAStack->isLoopControlVariable(VD) ||
894  (VD->hasLocalStorage() &&
895  isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
896  DSAStack->isForceVarCapturing())
897  return true;
898  auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isClauseParsingMode());
899  if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
900  return true;
901  DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(),
902  DSAStack->isClauseParsingMode());
903  return DVarPrivate.CKind != OMPC_unknown;
904  }
905  return false;
906 }
907 
908 bool Sema::isOpenMPPrivateVar(VarDecl *VD, unsigned Level) {
909  assert(LangOpts.OpenMP && "OpenMP is not allowed");
910  return DSAStack->hasExplicitDSA(
911  VD, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level);
912 }
913 
914 bool Sema::isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level) {
915  assert(LangOpts.OpenMP && "OpenMP is not allowed");
916  // Return true if the current level is no longer enclosed in a target region.
917 
918  return !VD->hasLocalStorage() &&
919  DSAStack->hasExplicitDirective(isOpenMPTargetDirective, Level);
920 }
921 
922 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
923 
925  const DeclarationNameInfo &DirName,
926  Scope *CurScope, SourceLocation Loc) {
927  DSAStack->push(DKind, DirName, CurScope, Loc);
929 }
930 
932  DSAStack->setClauseParsingMode(K);
933 }
934 
936  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
937 }
938 
939 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
940  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
941  // A variable of class type (or array thereof) that appears in a lastprivate
942  // clause requires an accessible, unambiguous default constructor for the
943  // class type, unless the list item is also specified in a firstprivate
944  // clause.
945  if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
946  for (auto *C : D->clauses()) {
947  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
948  SmallVector<Expr *, 8> PrivateCopies;
949  for (auto *DE : Clause->varlists()) {
950  if (DE->isValueDependent() || DE->isTypeDependent()) {
951  PrivateCopies.push_back(nullptr);
952  continue;
953  }
954  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(DE)->getDecl());
955  QualType Type = VD->getType().getNonReferenceType();
956  auto DVar = DSAStack->getTopDSA(VD, false);
957  if (DVar.CKind == OMPC_lastprivate) {
958  // Generate helper private variable and initialize it with the
959  // default value. The address of the original variable is replaced
960  // by the address of the new private variable in CodeGen. This new
961  // variable is not added to IdResolver, so the code in the OpenMP
962  // region uses original variable for proper diagnostics.
963  auto *VDPrivate = buildVarDecl(
964  *this, DE->getExprLoc(), Type.getUnqualifiedType(),
965  VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
966  ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
967  if (VDPrivate->isInvalidDecl())
968  continue;
969  PrivateCopies.push_back(buildDeclRefExpr(
970  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
971  } else {
972  // The variable is also a firstprivate, so initialization sequence
973  // for private copy is generated already.
974  PrivateCopies.push_back(nullptr);
975  }
976  }
977  // Set initializers to private copies if no errors were found.
978  if (PrivateCopies.size() == Clause->varlist_size()) {
979  Clause->setPrivateCopies(PrivateCopies);
980  }
981  }
982  }
983  }
984 
985  DSAStack->pop();
988 }
989 
990 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
991  Expr *NumIterations, Sema &SemaRef,
992  Scope *S);
993 
994 namespace {
995 
996 class VarDeclFilterCCC : public CorrectionCandidateCallback {
997 private:
998  Sema &SemaRef;
999 
1000 public:
1001  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1002  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1003  NamedDecl *ND = Candidate.getCorrectionDecl();
1004  if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
1005  return VD->hasGlobalStorage() &&
1006  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1007  SemaRef.getCurScope());
1008  }
1009  return false;
1010  }
1011 };
1012 } // namespace
1013 
1015  CXXScopeSpec &ScopeSpec,
1016  const DeclarationNameInfo &Id) {
1017  LookupResult Lookup(*this, Id, LookupOrdinaryName);
1018  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1019 
1020  if (Lookup.isAmbiguous())
1021  return ExprError();
1022 
1023  VarDecl *VD;
1024  if (!Lookup.isSingleResult()) {
1025  if (TypoCorrection Corrected = CorrectTypo(
1026  Id, LookupOrdinaryName, CurScope, nullptr,
1027  llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1028  diagnoseTypo(Corrected,
1029  PDiag(Lookup.empty()
1030  ? diag::err_undeclared_var_use_suggest
1031  : diag::err_omp_expected_var_arg_suggest)
1032  << Id.getName());
1033  VD = Corrected.getCorrectionDeclAs<VarDecl>();
1034  } else {
1035  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1036  : diag::err_omp_expected_var_arg)
1037  << Id.getName();
1038  return ExprError();
1039  }
1040  } else {
1041  if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1042  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1043  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1044  return ExprError();
1045  }
1046  }
1047  Lookup.suppressDiagnostics();
1048 
1049  // OpenMP [2.9.2, Syntax, C/C++]
1050  // Variables must be file-scope, namespace-scope, or static block-scope.
1051  if (!VD->hasGlobalStorage()) {
1052  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1053  << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1054  bool IsDecl =
1056  Diag(VD->getLocation(),
1057  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1058  << VD;
1059  return ExprError();
1060  }
1061 
1062  VarDecl *CanonicalVD = VD->getCanonicalDecl();
1063  NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1064  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1065  // A threadprivate directive for file-scope variables must appear outside
1066  // any definition or declaration.
1067  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1069  Diag(Id.getLoc(), diag::err_omp_var_scope)
1070  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1071  bool IsDecl =
1073  Diag(VD->getLocation(),
1074  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1075  << VD;
1076  return ExprError();
1077  }
1078  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1079  // A threadprivate directive for static class member variables must appear
1080  // in the class definition, in the same scope in which the member
1081  // variables are declared.
1082  if (CanonicalVD->isStaticDataMember() &&
1083  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1084  Diag(Id.getLoc(), diag::err_omp_var_scope)
1085  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1086  bool IsDecl =
1088  Diag(VD->getLocation(),
1089  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1090  << VD;
1091  return ExprError();
1092  }
1093  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1094  // A threadprivate directive for namespace-scope variables must appear
1095  // outside any definition or declaration other than the namespace
1096  // definition itself.
1097  if (CanonicalVD->getDeclContext()->isNamespace() &&
1099  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1100  Diag(Id.getLoc(), diag::err_omp_var_scope)
1101  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1102  bool IsDecl =
1104  Diag(VD->getLocation(),
1105  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1106  << VD;
1107  return ExprError();
1108  }
1109  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1110  // A threadprivate directive for static block-scope variables must appear
1111  // in the scope of the variable and not in a nested scope.
1112  if (CanonicalVD->isStaticLocal() && CurScope &&
1113  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1114  Diag(Id.getLoc(), diag::err_omp_var_scope)
1115  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1116  bool IsDecl =
1118  Diag(VD->getLocation(),
1119  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1120  << VD;
1121  return ExprError();
1122  }
1123 
1124  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1125  // A threadprivate directive must lexically precede all references to any
1126  // of the variables in its list.
1127  if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1128  Diag(Id.getLoc(), diag::err_omp_var_used)
1129  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1130  return ExprError();
1131  }
1132 
1133  QualType ExprType = VD->getType().getNonReferenceType();
1134  ExprResult DE = buildDeclRefExpr(*this, VD, ExprType, Id.getLoc());
1135  return DE;
1136 }
1137 
1140  ArrayRef<Expr *> VarList) {
1141  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1142  CurContext->addDecl(D);
1144  }
1145  return DeclGroupPtrTy();
1146 }
1147 
1148 namespace {
1149 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1150  Sema &SemaRef;
1151 
1152 public:
1153  bool VisitDeclRefExpr(const DeclRefExpr *E) {
1154  if (auto VD = dyn_cast<VarDecl>(E->getDecl())) {
1155  if (VD->hasLocalStorage()) {
1156  SemaRef.Diag(E->getLocStart(),
1157  diag::err_omp_local_var_in_threadprivate_init)
1158  << E->getSourceRange();
1159  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1160  << VD << VD->getSourceRange();
1161  return true;
1162  }
1163  }
1164  return false;
1165  }
1166  bool VisitStmt(const Stmt *S) {
1167  for (auto Child : S->children()) {
1168  if (Child && Visit(Child))
1169  return true;
1170  }
1171  return false;
1172  }
1173  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1174 };
1175 } // namespace
1176 
1180  for (auto &RefExpr : VarList) {
1181  DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
1182  VarDecl *VD = cast<VarDecl>(DE->getDecl());
1183  SourceLocation ILoc = DE->getExprLoc();
1184 
1185  QualType QType = VD->getType();
1186  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1187  // It will be analyzed later.
1188  Vars.push_back(DE);
1189  continue;
1190  }
1191 
1192  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1193  // A threadprivate variable must not have an incomplete type.
1194  if (RequireCompleteType(ILoc, VD->getType(),
1195  diag::err_omp_threadprivate_incomplete_type)) {
1196  continue;
1197  }
1198 
1199  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1200  // A threadprivate variable must not have a reference type.
1201  if (VD->getType()->isReferenceType()) {
1202  Diag(ILoc, diag::err_omp_ref_type_arg)
1203  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1204  bool IsDecl =
1205  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1206  Diag(VD->getLocation(),
1207  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1208  << VD;
1209  continue;
1210  }
1211 
1212  // Check if this is a TLS variable. If TLS is not being supported, produce
1213  // the corresponding diagnostic.
1214  if ((VD->getTLSKind() != VarDecl::TLS_None &&
1215  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1216  getLangOpts().OpenMPUseTLS &&
1218  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1219  !VD->isLocalVarDecl())) {
1220  Diag(ILoc, diag::err_omp_var_thread_local)
1221  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1222  bool IsDecl =
1223  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1224  Diag(VD->getLocation(),
1225  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1226  << VD;
1227  continue;
1228  }
1229 
1230  // Check if initial value of threadprivate variable reference variable with
1231  // local storage (it is not supported by runtime).
1232  if (auto Init = VD->getAnyInitializer()) {
1233  LocalVarRefChecker Checker(*this);
1234  if (Checker.Visit(Init))
1235  continue;
1236  }
1237 
1238  Vars.push_back(RefExpr);
1239  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1240  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1241  Context, SourceRange(Loc, Loc)));
1242  if (auto *ML = Context.getASTMutationListener())
1243  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1244  }
1245  OMPThreadPrivateDecl *D = nullptr;
1246  if (!Vars.empty()) {
1248  Vars);
1249  D->setAccess(AS_public);
1250  }
1251  return D;
1252 }
1253 
1254 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1255  const VarDecl *VD, DSAStackTy::DSAVarData DVar,
1256  bool IsLoopIterVar = false) {
1257  if (DVar.RefExpr) {
1258  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1259  << getOpenMPClauseName(DVar.CKind);
1260  return;
1261  }
1262  enum {
1263  PDSA_StaticMemberShared,
1264  PDSA_StaticLocalVarShared,
1265  PDSA_LoopIterVarPrivate,
1266  PDSA_LoopIterVarLinear,
1267  PDSA_LoopIterVarLastprivate,
1268  PDSA_ConstVarShared,
1269  PDSA_GlobalVarShared,
1270  PDSA_TaskVarFirstprivate,
1271  PDSA_LocalVarPrivate,
1272  PDSA_Implicit
1273  } Reason = PDSA_Implicit;
1274  bool ReportHint = false;
1275  auto ReportLoc = VD->getLocation();
1276  if (IsLoopIterVar) {
1277  if (DVar.CKind == OMPC_private)
1278  Reason = PDSA_LoopIterVarPrivate;
1279  else if (DVar.CKind == OMPC_lastprivate)
1280  Reason = PDSA_LoopIterVarLastprivate;
1281  else
1282  Reason = PDSA_LoopIterVarLinear;
1283  } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) {
1284  Reason = PDSA_TaskVarFirstprivate;
1285  ReportLoc = DVar.ImplicitDSALoc;
1286  } else if (VD->isStaticLocal())
1287  Reason = PDSA_StaticLocalVarShared;
1288  else if (VD->isStaticDataMember())
1289  Reason = PDSA_StaticMemberShared;
1290  else if (VD->isFileVarDecl())
1291  Reason = PDSA_GlobalVarShared;
1292  else if (VD->getType().isConstant(SemaRef.getASTContext()))
1293  Reason = PDSA_ConstVarShared;
1294  else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1295  ReportHint = true;
1296  Reason = PDSA_LocalVarPrivate;
1297  }
1298  if (Reason != PDSA_Implicit) {
1299  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1300  << Reason << ReportHint
1301  << getOpenMPDirectiveName(Stack->getCurrentDirective());
1302  } else if (DVar.ImplicitDSALoc.isValid()) {
1303  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1304  << getOpenMPClauseName(DVar.CKind);
1305  }
1306 }
1307 
1308 namespace {
1309 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1310  DSAStackTy *Stack;
1311  Sema &SemaRef;
1312  bool ErrorFound;
1313  CapturedStmt *CS;
1314  llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1315  llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
1316 
1317 public:
1318  void VisitDeclRefExpr(DeclRefExpr *E) {
1319  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1320  // Skip internally declared variables.
1321  if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
1322  return;
1323 
1324  auto DVar = Stack->getTopDSA(VD, false);
1325  // Check if the variable has explicit DSA set and stop analysis if it so.
1326  if (DVar.RefExpr) return;
1327 
1328  auto ELoc = E->getExprLoc();
1329  auto DKind = Stack->getCurrentDirective();
1330  // The default(none) clause requires that each variable that is referenced
1331  // in the construct, and does not have a predetermined data-sharing
1332  // attribute, must have its data-sharing attribute explicitly determined
1333  // by being listed in a data-sharing attribute clause.
1334  if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1335  isParallelOrTaskRegion(DKind) &&
1336  VarsWithInheritedDSA.count(VD) == 0) {
1337  VarsWithInheritedDSA[VD] = E;
1338  return;
1339  }
1340 
1341  // OpenMP [2.9.3.6, Restrictions, p.2]
1342  // A list item that appears in a reduction clause of the innermost
1343  // enclosing worksharing or parallel construct may not be accessed in an
1344  // explicit task.
1345  DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
1346  [](OpenMPDirectiveKind K) -> bool {
1347  return isOpenMPParallelDirective(K) ||
1350  },
1351  false);
1352  if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) {
1353  ErrorFound = true;
1354  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1355  ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1356  return;
1357  }
1358 
1359  // Define implicit data-sharing attributes for task.
1360  DVar = Stack->getImplicitDSA(VD, false);
1361  if (DKind == OMPD_task && DVar.CKind != OMPC_shared)
1362  ImplicitFirstprivate.push_back(E);
1363  }
1364  }
1365  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
1366  for (auto *C : S->clauses()) {
1367  // Skip analysis of arguments of implicitly defined firstprivate clause
1368  // for task directives.
1369  if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid()))
1370  for (auto *CC : C->children()) {
1371  if (CC)
1372  Visit(CC);
1373  }
1374  }
1375  }
1376  void VisitStmt(Stmt *S) {
1377  for (auto *C : S->children()) {
1378  if (C && !isa<OMPExecutableDirective>(C))
1379  Visit(C);
1380  }
1381  }
1382 
1383  bool isErrorFound() { return ErrorFound; }
1384  ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
1385  llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() {
1386  return VarsWithInheritedDSA;
1387  }
1388 
1389  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
1390  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
1391 };
1392 } // namespace
1393 
1395  switch (DKind) {
1396  case OMPD_parallel: {
1397  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1398  QualType KmpInt32PtrTy =
1399  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1400  Sema::CapturedParamNameType Params[] = {
1401  std::make_pair(".global_tid.", KmpInt32PtrTy),
1402  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1403  std::make_pair(StringRef(), QualType()) // __context with shared vars
1404  };
1405  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1406  Params);
1407  break;
1408  }
1409  case OMPD_simd: {
1410  Sema::CapturedParamNameType Params[] = {
1411  std::make_pair(StringRef(), QualType()) // __context with shared vars
1412  };
1413  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1414  Params);
1415  break;
1416  }
1417  case OMPD_for: {
1418  Sema::CapturedParamNameType Params[] = {
1419  std::make_pair(StringRef(), QualType()) // __context with shared vars
1420  };
1421  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1422  Params);
1423  break;
1424  }
1425  case OMPD_for_simd: {
1426  Sema::CapturedParamNameType Params[] = {
1427  std::make_pair(StringRef(), QualType()) // __context with shared vars
1428  };
1429  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1430  Params);
1431  break;
1432  }
1433  case OMPD_sections: {
1434  Sema::CapturedParamNameType Params[] = {
1435  std::make_pair(StringRef(), QualType()) // __context with shared vars
1436  };
1437  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1438  Params);
1439  break;
1440  }
1441  case OMPD_section: {
1442  Sema::CapturedParamNameType Params[] = {
1443  std::make_pair(StringRef(), QualType()) // __context with shared vars
1444  };
1445  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1446  Params);
1447  break;
1448  }
1449  case OMPD_single: {
1450  Sema::CapturedParamNameType Params[] = {
1451  std::make_pair(StringRef(), QualType()) // __context with shared vars
1452  };
1453  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1454  Params);
1455  break;
1456  }
1457  case OMPD_master: {
1458  Sema::CapturedParamNameType Params[] = {
1459  std::make_pair(StringRef(), QualType()) // __context with shared vars
1460  };
1461  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1462  Params);
1463  break;
1464  }
1465  case OMPD_critical: {
1466  Sema::CapturedParamNameType Params[] = {
1467  std::make_pair(StringRef(), QualType()) // __context with shared vars
1468  };
1469  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1470  Params);
1471  break;
1472  }
1473  case OMPD_parallel_for: {
1474  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1475  QualType KmpInt32PtrTy =
1476  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1477  Sema::CapturedParamNameType Params[] = {
1478  std::make_pair(".global_tid.", KmpInt32PtrTy),
1479  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1480  std::make_pair(StringRef(), QualType()) // __context with shared vars
1481  };
1482  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1483  Params);
1484  break;
1485  }
1486  case OMPD_parallel_for_simd: {
1487  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1488  QualType KmpInt32PtrTy =
1489  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1490  Sema::CapturedParamNameType Params[] = {
1491  std::make_pair(".global_tid.", KmpInt32PtrTy),
1492  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1493  std::make_pair(StringRef(), QualType()) // __context with shared vars
1494  };
1495  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1496  Params);
1497  break;
1498  }
1499  case OMPD_parallel_sections: {
1500  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1501  QualType KmpInt32PtrTy =
1502  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1503  Sema::CapturedParamNameType Params[] = {
1504  std::make_pair(".global_tid.", KmpInt32PtrTy),
1505  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1506  std::make_pair(StringRef(), QualType()) // __context with shared vars
1507  };
1508  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1509  Params);
1510  break;
1511  }
1512  case OMPD_task: {
1513  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1516  EPI.Variadic = true;
1517  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
1518  Sema::CapturedParamNameType Params[] = {
1519  std::make_pair(".global_tid.", KmpInt32Ty),
1520  std::make_pair(".part_id.", KmpInt32Ty),
1521  std::make_pair(".privates.",
1523  std::make_pair(
1524  ".copy_fn.",
1525  Context.getPointerType(CopyFnType).withConst().withRestrict()),
1526  std::make_pair(StringRef(), QualType()) // __context with shared vars
1527  };
1528  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1529  Params);
1530  // Mark this captured region as inlined, because we don't use outlined
1531  // function directly.
1533  AlwaysInlineAttr::CreateImplicit(
1534  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
1535  break;
1536  }
1537  case OMPD_ordered: {
1538  Sema::CapturedParamNameType Params[] = {
1539  std::make_pair(StringRef(), QualType()) // __context with shared vars
1540  };
1541  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1542  Params);
1543  break;
1544  }
1545  case OMPD_atomic: {
1546  Sema::CapturedParamNameType Params[] = {
1547  std::make_pair(StringRef(), QualType()) // __context with shared vars
1548  };
1549  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1550  Params);
1551  break;
1552  }
1553  case OMPD_target_data:
1554  case OMPD_target: {
1555  Sema::CapturedParamNameType Params[] = {
1556  std::make_pair(StringRef(), QualType()) // __context with shared vars
1557  };
1558  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1559  Params);
1560  break;
1561  }
1562  case OMPD_teams: {
1563  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1564  QualType KmpInt32PtrTy =
1565  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1566  Sema::CapturedParamNameType Params[] = {
1567  std::make_pair(".global_tid.", KmpInt32PtrTy),
1568  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1569  std::make_pair(StringRef(), QualType()) // __context with shared vars
1570  };
1571  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1572  Params);
1573  break;
1574  }
1575  case OMPD_taskgroup: {
1576  Sema::CapturedParamNameType Params[] = {
1577  std::make_pair(StringRef(), QualType()) // __context with shared vars
1578  };
1579  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1580  Params);
1581  break;
1582  }
1583  case OMPD_taskloop: {
1584  Sema::CapturedParamNameType Params[] = {
1585  std::make_pair(StringRef(), QualType()) // __context with shared vars
1586  };
1587  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1588  Params);
1589  break;
1590  }
1591  case OMPD_taskloop_simd: {
1592  Sema::CapturedParamNameType Params[] = {
1593  std::make_pair(StringRef(), QualType()) // __context with shared vars
1594  };
1595  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1596  Params);
1597  break;
1598  }
1599  case OMPD_distribute: {
1600  Sema::CapturedParamNameType Params[] = {
1601  std::make_pair(StringRef(), QualType()) // __context with shared vars
1602  };
1603  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1604  Params);
1605  break;
1606  }
1607  case OMPD_threadprivate:
1608  case OMPD_taskyield:
1609  case OMPD_barrier:
1610  case OMPD_taskwait:
1611  case OMPD_cancellation_point:
1612  case OMPD_cancel:
1613  case OMPD_flush:
1614  llvm_unreachable("OpenMP Directive is not allowed");
1615  case OMPD_unknown:
1616  llvm_unreachable("Unknown OpenMP directive");
1617  }
1618 }
1619 
1621  ArrayRef<OMPClause *> Clauses) {
1622  if (!S.isUsable()) {
1624  return StmtError();
1625  }
1626 
1627  OMPOrderedClause *OC = nullptr;
1628  OMPScheduleClause *SC = nullptr;
1630  // This is required for proper codegen.
1631  for (auto *Clause : Clauses) {
1632  if (isOpenMPPrivate(Clause->getClauseKind()) ||
1633  Clause->getClauseKind() == OMPC_copyprivate ||
1634  (getLangOpts().OpenMPUseTLS &&
1636  Clause->getClauseKind() == OMPC_copyin)) {
1637  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
1638  // Mark all variables in private list clauses as used in inner region.
1639  for (auto *VarRef : Clause->children()) {
1640  if (auto *E = cast_or_null<Expr>(VarRef)) {
1642  }
1643  }
1644  DSAStack->setForceVarCapturing(/*V=*/false);
1645  } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) &&
1646  Clause->getClauseKind() == OMPC_schedule) {
1647  // Mark all variables in private list clauses as used in inner region.
1648  // Required for proper codegen of combined directives.
1649  // TODO: add processing for other clauses.
1650  if (auto *E = cast_or_null<Expr>(
1651  cast<OMPScheduleClause>(Clause)->getHelperChunkSize()))
1653  }
1654  if (Clause->getClauseKind() == OMPC_schedule)
1655  SC = cast<OMPScheduleClause>(Clause);
1656  else if (Clause->getClauseKind() == OMPC_ordered)
1657  OC = cast<OMPOrderedClause>(Clause);
1658  else if (Clause->getClauseKind() == OMPC_linear)
1659  LCs.push_back(cast<OMPLinearClause>(Clause));
1660  }
1661  bool ErrorFound = false;
1662  // OpenMP, 2.7.1 Loop Construct, Restrictions
1663  // The nonmonotonic modifier cannot be specified if an ordered clause is
1664  // specified.
1665  if (SC &&
1666  (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
1667  SC->getSecondScheduleModifier() ==
1668  OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
1669  OC) {
1670  Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
1673  diag::err_omp_schedule_nonmonotonic_ordered)
1674  << SourceRange(OC->getLocStart(), OC->getLocEnd());
1675  ErrorFound = true;
1676  }
1677  if (!LCs.empty() && OC && OC->getNumForLoops()) {
1678  for (auto *C : LCs) {
1679  Diag(C->getLocStart(), diag::err_omp_linear_ordered)
1680  << SourceRange(OC->getLocStart(), OC->getLocEnd());
1681  }
1682  ErrorFound = true;
1683  }
1684  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
1685  isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
1686  OC->getNumForLoops()) {
1687  Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
1688  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
1689  ErrorFound = true;
1690  }
1691  if (ErrorFound) {
1693  return StmtError();
1694  }
1695  return ActOnCapturedRegionEnd(S.get());
1696 }
1697 
1698 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
1699  OpenMPDirectiveKind CurrentRegion,
1700  const DeclarationNameInfo &CurrentName,
1701  OpenMPDirectiveKind CancelRegion,
1702  SourceLocation StartLoc) {
1703  // Allowed nesting of constructs
1704  // +------------------+-----------------+------------------------------------+
1705  // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)|
1706  // +------------------+-----------------+------------------------------------+
1707  // | parallel | parallel | * |
1708  // | parallel | for | * |
1709  // | parallel | for simd | * |
1710  // | parallel | master | * |
1711  // | parallel | critical | * |
1712  // | parallel | simd | * |
1713  // | parallel | sections | * |
1714  // | parallel | section | + |
1715  // | parallel | single | * |
1716  // | parallel | parallel for | * |
1717  // | parallel |parallel for simd| * |
1718  // | parallel |parallel sections| * |
1719  // | parallel | task | * |
1720  // | parallel | taskyield | * |
1721  // | parallel | barrier | * |
1722  // | parallel | taskwait | * |
1723  // | parallel | taskgroup | * |
1724  // | parallel | flush | * |
1725  // | parallel | ordered | + |
1726  // | parallel | atomic | * |
1727  // | parallel | target | * |
1728  // | parallel | teams | + |
1729  // | parallel | cancellation | |
1730  // | | point | ! |
1731  // | parallel | cancel | ! |
1732  // | parallel | taskloop | * |
1733  // | parallel | taskloop simd | * |
1734  // | parallel | distribute | |
1735  // +------------------+-----------------+------------------------------------+
1736  // | for | parallel | * |
1737  // | for | for | + |
1738  // | for | for simd | + |
1739  // | for | master | + |
1740  // | for | critical | * |
1741  // | for | simd | * |
1742  // | for | sections | + |
1743  // | for | section | + |
1744  // | for | single | + |
1745  // | for | parallel for | * |
1746  // | for |parallel for simd| * |
1747  // | for |parallel sections| * |
1748  // | for | task | * |
1749  // | for | taskyield | * |
1750  // | for | barrier | + |
1751  // | for | taskwait | * |
1752  // | for | taskgroup | * |
1753  // | for | flush | * |
1754  // | for | ordered | * (if construct is ordered) |
1755  // | for | atomic | * |
1756  // | for | target | * |
1757  // | for | teams | + |
1758  // | for | cancellation | |
1759  // | | point | ! |
1760  // | for | cancel | ! |
1761  // | for | taskloop | * |
1762  // | for | taskloop simd | * |
1763  // | for | distribute | |
1764  // +------------------+-----------------+------------------------------------+
1765  // | master | parallel | * |
1766  // | master | for | + |
1767  // | master | for simd | + |
1768  // | master | master | * |
1769  // | master | critical | * |
1770  // | master | simd | * |
1771  // | master | sections | + |
1772  // | master | section | + |
1773  // | master | single | + |
1774  // | master | parallel for | * |
1775  // | master |parallel for simd| * |
1776  // | master |parallel sections| * |
1777  // | master | task | * |
1778  // | master | taskyield | * |
1779  // | master | barrier | + |
1780  // | master | taskwait | * |
1781  // | master | taskgroup | * |
1782  // | master | flush | * |
1783  // | master | ordered | + |
1784  // | master | atomic | * |
1785  // | master | target | * |
1786  // | master | teams | + |
1787  // | master | cancellation | |
1788  // | | point | |
1789  // | master | cancel | |
1790  // | master | taskloop | * |
1791  // | master | taskloop simd | * |
1792  // | master | distribute | |
1793  // +------------------+-----------------+------------------------------------+
1794  // | critical | parallel | * |
1795  // | critical | for | + |
1796  // | critical | for simd | + |
1797  // | critical | master | * |
1798  // | critical | critical | * (should have different names) |
1799  // | critical | simd | * |
1800  // | critical | sections | + |
1801  // | critical | section | + |
1802  // | critical | single | + |
1803  // | critical | parallel for | * |
1804  // | critical |parallel for simd| * |
1805  // | critical |parallel sections| * |
1806  // | critical | task | * |
1807  // | critical | taskyield | * |
1808  // | critical | barrier | + |
1809  // | critical | taskwait | * |
1810  // | critical | taskgroup | * |
1811  // | critical | ordered | + |
1812  // | critical | atomic | * |
1813  // | critical | target | * |
1814  // | critical | teams | + |
1815  // | critical | cancellation | |
1816  // | | point | |
1817  // | critical | cancel | |
1818  // | critical | taskloop | * |
1819  // | critical | taskloop simd | * |
1820  // | critical | distribute | |
1821  // +------------------+-----------------+------------------------------------+
1822  // | simd | parallel | |
1823  // | simd | for | |
1824  // | simd | for simd | |
1825  // | simd | master | |
1826  // | simd | critical | |
1827  // | simd | simd | |
1828  // | simd | sections | |
1829  // | simd | section | |
1830  // | simd | single | |
1831  // | simd | parallel for | |
1832  // | simd |parallel for simd| |
1833  // | simd |parallel sections| |
1834  // | simd | task | |
1835  // | simd | taskyield | |
1836  // | simd | barrier | |
1837  // | simd | taskwait | |
1838  // | simd | taskgroup | |
1839  // | simd | flush | |
1840  // | simd | ordered | + (with simd clause) |
1841  // | simd | atomic | |
1842  // | simd | target | |
1843  // | simd | teams | |
1844  // | simd | cancellation | |
1845  // | | point | |
1846  // | simd | cancel | |
1847  // | simd | taskloop | |
1848  // | simd | taskloop simd | |
1849  // | simd | distribute | |
1850  // +------------------+-----------------+------------------------------------+
1851  // | for simd | parallel | |
1852  // | for simd | for | |
1853  // | for simd | for simd | |
1854  // | for simd | master | |
1855  // | for simd | critical | |
1856  // | for simd | simd | |
1857  // | for simd | sections | |
1858  // | for simd | section | |
1859  // | for simd | single | |
1860  // | for simd | parallel for | |
1861  // | for simd |parallel for simd| |
1862  // | for simd |parallel sections| |
1863  // | for simd | task | |
1864  // | for simd | taskyield | |
1865  // | for simd | barrier | |
1866  // | for simd | taskwait | |
1867  // | for simd | taskgroup | |
1868  // | for simd | flush | |
1869  // | for simd | ordered | + (with simd clause) |
1870  // | for simd | atomic | |
1871  // | for simd | target | |
1872  // | for simd | teams | |
1873  // | for simd | cancellation | |
1874  // | | point | |
1875  // | for simd | cancel | |
1876  // | for simd | taskloop | |
1877  // | for simd | taskloop simd | |
1878  // | for simd | distribute | |
1879  // +------------------+-----------------+------------------------------------+
1880  // | parallel for simd| parallel | |
1881  // | parallel for simd| for | |
1882  // | parallel for simd| for simd | |
1883  // | parallel for simd| master | |
1884  // | parallel for simd| critical | |
1885  // | parallel for simd| simd | |
1886  // | parallel for simd| sections | |
1887  // | parallel for simd| section | |
1888  // | parallel for simd| single | |
1889  // | parallel for simd| parallel for | |
1890  // | parallel for simd|parallel for simd| |
1891  // | parallel for simd|parallel sections| |
1892  // | parallel for simd| task | |
1893  // | parallel for simd| taskyield | |
1894  // | parallel for simd| barrier | |
1895  // | parallel for simd| taskwait | |
1896  // | parallel for simd| taskgroup | |
1897  // | parallel for simd| flush | |
1898  // | parallel for simd| ordered | + (with simd clause) |
1899  // | parallel for simd| atomic | |
1900  // | parallel for simd| target | |
1901  // | parallel for simd| teams | |
1902  // | parallel for simd| cancellation | |
1903  // | | point | |
1904  // | parallel for simd| cancel | |
1905  // | parallel for simd| taskloop | |
1906  // | parallel for simd| taskloop simd | |
1907  // | parallel for simd| distribute | |
1908  // +------------------+-----------------+------------------------------------+
1909  // | sections | parallel | * |
1910  // | sections | for | + |
1911  // | sections | for simd | + |
1912  // | sections | master | + |
1913  // | sections | critical | * |
1914  // | sections | simd | * |
1915  // | sections | sections | + |
1916  // | sections | section | * |
1917  // | sections | single | + |
1918  // | sections | parallel for | * |
1919  // | sections |parallel for simd| * |
1920  // | sections |parallel sections| * |
1921  // | sections | task | * |
1922  // | sections | taskyield | * |
1923  // | sections | barrier | + |
1924  // | sections | taskwait | * |
1925  // | sections | taskgroup | * |
1926  // | sections | flush | * |
1927  // | sections | ordered | + |
1928  // | sections | atomic | * |
1929  // | sections | target | * |
1930  // | sections | teams | + |
1931  // | sections | cancellation | |
1932  // | | point | ! |
1933  // | sections | cancel | ! |
1934  // | sections | taskloop | * |
1935  // | sections | taskloop simd | * |
1936  // | sections | distribute | |
1937  // +------------------+-----------------+------------------------------------+
1938  // | section | parallel | * |
1939  // | section | for | + |
1940  // | section | for simd | + |
1941  // | section | master | + |
1942  // | section | critical | * |
1943  // | section | simd | * |
1944  // | section | sections | + |
1945  // | section | section | + |
1946  // | section | single | + |
1947  // | section | parallel for | * |
1948  // | section |parallel for simd| * |
1949  // | section |parallel sections| * |
1950  // | section | task | * |
1951  // | section | taskyield | * |
1952  // | section | barrier | + |
1953  // | section | taskwait | * |
1954  // | section | taskgroup | * |
1955  // | section | flush | * |
1956  // | section | ordered | + |
1957  // | section | atomic | * |
1958  // | section | target | * |
1959  // | section | teams | + |
1960  // | section | cancellation | |
1961  // | | point | ! |
1962  // | section | cancel | ! |
1963  // | section | taskloop | * |
1964  // | section | taskloop simd | * |
1965  // | section | distribute | |
1966  // +------------------+-----------------+------------------------------------+
1967  // | single | parallel | * |
1968  // | single | for | + |
1969  // | single | for simd | + |
1970  // | single | master | + |
1971  // | single | critical | * |
1972  // | single | simd | * |
1973  // | single | sections | + |
1974  // | single | section | + |
1975  // | single | single | + |
1976  // | single | parallel for | * |
1977  // | single |parallel for simd| * |
1978  // | single |parallel sections| * |
1979  // | single | task | * |
1980  // | single | taskyield | * |
1981  // | single | barrier | + |
1982  // | single | taskwait | * |
1983  // | single | taskgroup | * |
1984  // | single | flush | * |
1985  // | single | ordered | + |
1986  // | single | atomic | * |
1987  // | single | target | * |
1988  // | single | teams | + |
1989  // | single | cancellation | |
1990  // | | point | |
1991  // | single | cancel | |
1992  // | single | taskloop | * |
1993  // | single | taskloop simd | * |
1994  // | single | distribute | |
1995  // +------------------+-----------------+------------------------------------+
1996  // | parallel for | parallel | * |
1997  // | parallel for | for | + |
1998  // | parallel for | for simd | + |
1999  // | parallel for | master | + |
2000  // | parallel for | critical | * |
2001  // | parallel for | simd | * |
2002  // | parallel for | sections | + |
2003  // | parallel for | section | + |
2004  // | parallel for | single | + |
2005  // | parallel for | parallel for | * |
2006  // | parallel for |parallel for simd| * |
2007  // | parallel for |parallel sections| * |
2008  // | parallel for | task | * |
2009  // | parallel for | taskyield | * |
2010  // | parallel for | barrier | + |
2011  // | parallel for | taskwait | * |
2012  // | parallel for | taskgroup | * |
2013  // | parallel for | flush | * |
2014  // | parallel for | ordered | * (if construct is ordered) |
2015  // | parallel for | atomic | * |
2016  // | parallel for | target | * |
2017  // | parallel for | teams | + |
2018  // | parallel for | cancellation | |
2019  // | | point | ! |
2020  // | parallel for | cancel | ! |
2021  // | parallel for | taskloop | * |
2022  // | parallel for | taskloop simd | * |
2023  // | parallel for | distribute | |
2024  // +------------------+-----------------+------------------------------------+
2025  // | parallel sections| parallel | * |
2026  // | parallel sections| for | + |
2027  // | parallel sections| for simd | + |
2028  // | parallel sections| master | + |
2029  // | parallel sections| critical | + |
2030  // | parallel sections| simd | * |
2031  // | parallel sections| sections | + |
2032  // | parallel sections| section | * |
2033  // | parallel sections| single | + |
2034  // | parallel sections| parallel for | * |
2035  // | parallel sections|parallel for simd| * |
2036  // | parallel sections|parallel sections| * |
2037  // | parallel sections| task | * |
2038  // | parallel sections| taskyield | * |
2039  // | parallel sections| barrier | + |
2040  // | parallel sections| taskwait | * |
2041  // | parallel sections| taskgroup | * |
2042  // | parallel sections| flush | * |
2043  // | parallel sections| ordered | + |
2044  // | parallel sections| atomic | * |
2045  // | parallel sections| target | * |
2046  // | parallel sections| teams | + |
2047  // | parallel sections| cancellation | |
2048  // | | point | ! |
2049  // | parallel sections| cancel | ! |
2050  // | parallel sections| taskloop | * |
2051  // | parallel sections| taskloop simd | * |
2052  // | parallel sections| distribute | |
2053  // +------------------+-----------------+------------------------------------+
2054  // | task | parallel | * |
2055  // | task | for | + |
2056  // | task | for simd | + |
2057  // | task | master | + |
2058  // | task | critical | * |
2059  // | task | simd | * |
2060  // | task | sections | + |
2061  // | task | section | + |
2062  // | task | single | + |
2063  // | task | parallel for | * |
2064  // | task |parallel for simd| * |
2065  // | task |parallel sections| * |
2066  // | task | task | * |
2067  // | task | taskyield | * |
2068  // | task | barrier | + |
2069  // | task | taskwait | * |
2070  // | task | taskgroup | * |
2071  // | task | flush | * |
2072  // | task | ordered | + |
2073  // | task | atomic | * |
2074  // | task | target | * |
2075  // | task | teams | + |
2076  // | task | cancellation | |
2077  // | | point | ! |
2078  // | task | cancel | ! |
2079  // | task | taskloop | * |
2080  // | task | taskloop simd | * |
2081  // | task | distribute | |
2082  // +------------------+-----------------+------------------------------------+
2083  // | ordered | parallel | * |
2084  // | ordered | for | + |
2085  // | ordered | for simd | + |
2086  // | ordered | master | * |
2087  // | ordered | critical | * |
2088  // | ordered | simd | * |
2089  // | ordered | sections | + |
2090  // | ordered | section | + |
2091  // | ordered | single | + |
2092  // | ordered | parallel for | * |
2093  // | ordered |parallel for simd| * |
2094  // | ordered |parallel sections| * |
2095  // | ordered | task | * |
2096  // | ordered | taskyield | * |
2097  // | ordered | barrier | + |
2098  // | ordered | taskwait | * |
2099  // | ordered | taskgroup | * |
2100  // | ordered | flush | * |
2101  // | ordered | ordered | + |
2102  // | ordered | atomic | * |
2103  // | ordered | target | * |
2104  // | ordered | teams | + |
2105  // | ordered | cancellation | |
2106  // | | point | |
2107  // | ordered | cancel | |
2108  // | ordered | taskloop | * |
2109  // | ordered | taskloop simd | * |
2110  // | ordered | distribute | |
2111  // +------------------+-----------------+------------------------------------+
2112  // | atomic | parallel | |
2113  // | atomic | for | |
2114  // | atomic | for simd | |
2115  // | atomic | master | |
2116  // | atomic | critical | |
2117  // | atomic | simd | |
2118  // | atomic | sections | |
2119  // | atomic | section | |
2120  // | atomic | single | |
2121  // | atomic | parallel for | |
2122  // | atomic |parallel for simd| |
2123  // | atomic |parallel sections| |
2124  // | atomic | task | |
2125  // | atomic | taskyield | |
2126  // | atomic | barrier | |
2127  // | atomic | taskwait | |
2128  // | atomic | taskgroup | |
2129  // | atomic | flush | |
2130  // | atomic | ordered | |
2131  // | atomic | atomic | |
2132  // | atomic | target | |
2133  // | atomic | teams | |
2134  // | atomic | cancellation | |
2135  // | | point | |
2136  // | atomic | cancel | |
2137  // | atomic | taskloop | |
2138  // | atomic | taskloop simd | |
2139  // | atomic | distribute | |
2140  // +------------------+-----------------+------------------------------------+
2141  // | target | parallel | * |
2142  // | target | for | * |
2143  // | target | for simd | * |
2144  // | target | master | * |
2145  // | target | critical | * |
2146  // | target | simd | * |
2147  // | target | sections | * |
2148  // | target | section | * |
2149  // | target | single | * |
2150  // | target | parallel for | * |
2151  // | target |parallel for simd| * |
2152  // | target |parallel sections| * |
2153  // | target | task | * |
2154  // | target | taskyield | * |
2155  // | target | barrier | * |
2156  // | target | taskwait | * |
2157  // | target | taskgroup | * |
2158  // | target | flush | * |
2159  // | target | ordered | * |
2160  // | target | atomic | * |
2161  // | target | target | * |
2162  // | target | teams | * |
2163  // | target | cancellation | |
2164  // | | point | |
2165  // | target | cancel | |
2166  // | target | taskloop | * |
2167  // | target | taskloop simd | * |
2168  // | target | distribute | |
2169  // +------------------+-----------------+------------------------------------+
2170  // | teams | parallel | * |
2171  // | teams | for | + |
2172  // | teams | for simd | + |
2173  // | teams | master | + |
2174  // | teams | critical | + |
2175  // | teams | simd | + |
2176  // | teams | sections | + |
2177  // | teams | section | + |
2178  // | teams | single | + |
2179  // | teams | parallel for | * |
2180  // | teams |parallel for simd| * |
2181  // | teams |parallel sections| * |
2182  // | teams | task | + |
2183  // | teams | taskyield | + |
2184  // | teams | barrier | + |
2185  // | teams | taskwait | + |
2186  // | teams | taskgroup | + |
2187  // | teams | flush | + |
2188  // | teams | ordered | + |
2189  // | teams | atomic | + |
2190  // | teams | target | + |
2191  // | teams | teams | + |
2192  // | teams | cancellation | |
2193  // | | point | |
2194  // | teams | cancel | |
2195  // | teams | taskloop | + |
2196  // | teams | taskloop simd | + |
2197  // | teams | distribute | ! |
2198  // +------------------+-----------------+------------------------------------+
2199  // | taskloop | parallel | * |
2200  // | taskloop | for | + |
2201  // | taskloop | for simd | + |
2202  // | taskloop | master | + |
2203  // | taskloop | critical | * |
2204  // | taskloop | simd | * |
2205  // | taskloop | sections | + |
2206  // | taskloop | section | + |
2207  // | taskloop | single | + |
2208  // | taskloop | parallel for | * |
2209  // | taskloop |parallel for simd| * |
2210  // | taskloop |parallel sections| * |
2211  // | taskloop | task | * |
2212  // | taskloop | taskyield | * |
2213  // | taskloop | barrier | + |
2214  // | taskloop | taskwait | * |
2215  // | taskloop | taskgroup | * |
2216  // | taskloop | flush | * |
2217  // | taskloop | ordered | + |
2218  // | taskloop | atomic | * |
2219  // | taskloop | target | * |
2220  // | taskloop | teams | + |
2221  // | taskloop | cancellation | |
2222  // | | point | |
2223  // | taskloop | cancel | |
2224  // | taskloop | taskloop | * |
2225  // | taskloop | distribute | |
2226  // +------------------+-----------------+------------------------------------+
2227  // | taskloop simd | parallel | |
2228  // | taskloop simd | for | |
2229  // | taskloop simd | for simd | |
2230  // | taskloop simd | master | |
2231  // | taskloop simd | critical | |
2232  // | taskloop simd | simd | |
2233  // | taskloop simd | sections | |
2234  // | taskloop simd | section | |
2235  // | taskloop simd | single | |
2236  // | taskloop simd | parallel for | |
2237  // | taskloop simd |parallel for simd| |
2238  // | taskloop simd |parallel sections| |
2239  // | taskloop simd | task | |
2240  // | taskloop simd | taskyield | |
2241  // | taskloop simd | barrier | |
2242  // | taskloop simd | taskwait | |
2243  // | taskloop simd | taskgroup | |
2244  // | taskloop simd | flush | |
2245  // | taskloop simd | ordered | + (with simd clause) |
2246  // | taskloop simd | atomic | |
2247  // | taskloop simd | target | |
2248  // | taskloop simd | teams | |
2249  // | taskloop simd | cancellation | |
2250  // | | point | |
2251  // | taskloop simd | cancel | |
2252  // | taskloop simd | taskloop | |
2253  // | taskloop simd | taskloop simd | |
2254  // | taskloop simd | distribute | |
2255  // +------------------+-----------------+------------------------------------+
2256  // | distribute | parallel | * |
2257  // | distribute | for | * |
2258  // | distribute | for simd | * |
2259  // | distribute | master | * |
2260  // | distribute | critical | * |
2261  // | distribute | simd | * |
2262  // | distribute | sections | * |
2263  // | distribute | section | * |
2264  // | distribute | single | * |
2265  // | distribute | parallel for | * |
2266  // | distribute |parallel for simd| * |
2267  // | distribute |parallel sections| * |
2268  // | distribute | task | * |
2269  // | distribute | taskyield | * |
2270  // | distribute | barrier | * |
2271  // | distribute | taskwait | * |
2272  // | distribute | taskgroup | * |
2273  // | distribute | flush | * |
2274  // | distribute | ordered | + |
2275  // | distribute | atomic | * |
2276  // | distribute | target | |
2277  // | distribute | teams | |
2278  // | distribute | cancellation | + |
2279  // | | point | |
2280  // | distribute | cancel | + |
2281  // | distribute | taskloop | * |
2282  // | distribute | taskloop simd | * |
2283  // | distribute | distribute | |
2284  // +------------------+-----------------+------------------------------------+
2285  if (Stack->getCurScope()) {
2286  auto ParentRegion = Stack->getParentDirective();
2287  bool NestingProhibited = false;
2288  bool CloseNesting = true;
2289  enum {
2290  NoRecommend,
2291  ShouldBeInParallelRegion,
2292  ShouldBeInOrderedRegion,
2293  ShouldBeInTargetRegion,
2294  ShouldBeInTeamsRegion
2295  } Recommend = NoRecommend;
2296  if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2297  // OpenMP [2.16, Nesting of Regions]
2298  // OpenMP constructs may not be nested inside a simd region.
2299  // OpenMP [2.8.1,simd Construct, Restrictions]
2300  // An ordered construct with the simd clause is the only OpenMP construct
2301  // that can appear in the simd region.
2302  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
2303  return true;
2304  }
2305  if (ParentRegion == OMPD_atomic) {
2306  // OpenMP [2.16, Nesting of Regions]
2307  // OpenMP constructs may not be nested inside an atomic region.
2308  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2309  return true;
2310  }
2311  if (CurrentRegion == OMPD_section) {
2312  // OpenMP [2.7.2, sections Construct, Restrictions]
2313  // Orphaned section directives are prohibited. That is, the section
2314  // directives must appear within the sections construct and must not be
2315  // encountered elsewhere in the sections region.
2316  if (ParentRegion != OMPD_sections &&
2317  ParentRegion != OMPD_parallel_sections) {
2318  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2319  << (ParentRegion != OMPD_unknown)
2320  << getOpenMPDirectiveName(ParentRegion);
2321  return true;
2322  }
2323  return false;
2324  }
2325  // Allow some constructs to be orphaned (they could be used in functions,
2326  // called from OpenMP regions with the required preconditions).
2327  if (ParentRegion == OMPD_unknown)
2328  return false;
2329  if (CurrentRegion == OMPD_cancellation_point ||
2330  CurrentRegion == OMPD_cancel) {
2331  // OpenMP [2.16, Nesting of Regions]
2332  // A cancellation point construct for which construct-type-clause is
2333  // taskgroup must be nested inside a task construct. A cancellation
2334  // point construct for which construct-type-clause is not taskgroup must
2335  // be closely nested inside an OpenMP construct that matches the type
2336  // specified in construct-type-clause.
2337  // A cancel construct for which construct-type-clause is taskgroup must be
2338  // nested inside a task construct. A cancel construct for which
2339  // construct-type-clause is not taskgroup must be closely nested inside an
2340  // OpenMP construct that matches the type specified in
2341  // construct-type-clause.
2342  NestingProhibited =
2343  !((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) ||
2344  (CancelRegion == OMPD_for &&
2345  (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for)) ||
2346  (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2347  (CancelRegion == OMPD_sections &&
2348  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2349  ParentRegion == OMPD_parallel_sections)));
2350  } else if (CurrentRegion == OMPD_master) {
2351  // OpenMP [2.16, Nesting of Regions]
2352  // A master region may not be closely nested inside a worksharing,
2353  // atomic, or explicit task region.
2354  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2355  ParentRegion == OMPD_task ||
2356  isOpenMPTaskLoopDirective(ParentRegion);
2357  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2358  // OpenMP [2.16, Nesting of Regions]
2359  // A critical region may not be nested (closely or otherwise) inside a
2360  // critical region with the same name. Note that this restriction is not
2361  // sufficient to prevent deadlock.
2362  SourceLocation PreviousCriticalLoc;
2363  bool DeadLock =
2364  Stack->hasDirective([CurrentName, &PreviousCriticalLoc](
2366  const DeclarationNameInfo &DNI,
2367  SourceLocation Loc)
2368  ->bool {
2369  if (K == OMPD_critical &&
2370  DNI.getName() == CurrentName.getName()) {
2371  PreviousCriticalLoc = Loc;
2372  return true;
2373  } else
2374  return false;
2375  },
2376  false /* skip top directive */);
2377  if (DeadLock) {
2378  SemaRef.Diag(StartLoc,
2379  diag::err_omp_prohibited_region_critical_same_name)
2380  << CurrentName.getName();
2381  if (PreviousCriticalLoc.isValid())
2382  SemaRef.Diag(PreviousCriticalLoc,
2383  diag::note_omp_previous_critical_region);
2384  return true;
2385  }
2386  } else if (CurrentRegion == OMPD_barrier) {
2387  // OpenMP [2.16, Nesting of Regions]
2388  // A barrier region may not be closely nested inside a worksharing,
2389  // explicit task, critical, ordered, atomic, or master region.
2390  NestingProhibited =
2391  isOpenMPWorksharingDirective(ParentRegion) ||
2392  ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
2393  ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered ||
2394  isOpenMPTaskLoopDirective(ParentRegion);
2395  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2396  !isOpenMPParallelDirective(CurrentRegion)) {
2397  // OpenMP [2.16, Nesting of Regions]
2398  // A worksharing region may not be closely nested inside a worksharing,
2399  // explicit task, critical, ordered, atomic, or master region.
2400  NestingProhibited =
2401  isOpenMPWorksharingDirective(ParentRegion) ||
2402  ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
2403  ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered ||
2404  isOpenMPTaskLoopDirective(ParentRegion);
2405  Recommend = ShouldBeInParallelRegion;
2406  } else if (CurrentRegion == OMPD_ordered) {
2407  // OpenMP [2.16, Nesting of Regions]
2408  // An ordered region may not be closely nested inside a critical,
2409  // atomic, or explicit task region.
2410  // An ordered region must be closely nested inside a loop region (or
2411  // parallel loop region) with an ordered clause.
2412  // OpenMP [2.8.1,simd Construct, Restrictions]
2413  // An ordered construct with the simd clause is the only OpenMP construct
2414  // that can appear in the simd region.
2415  NestingProhibited = ParentRegion == OMPD_critical ||
2416  ParentRegion == OMPD_task ||
2417  isOpenMPTaskLoopDirective(ParentRegion) ||
2418  !(isOpenMPSimdDirective(ParentRegion) ||
2419  Stack->isParentOrderedRegion());
2420  Recommend = ShouldBeInOrderedRegion;
2421  } else if (isOpenMPTeamsDirective(CurrentRegion)) {
2422  // OpenMP [2.16, Nesting of Regions]
2423  // If specified, a teams construct must be contained within a target
2424  // construct.
2425  NestingProhibited = ParentRegion != OMPD_target;
2426  Recommend = ShouldBeInTargetRegion;
2427  Stack->setParentTeamsRegionLoc(Stack->getConstructLoc());
2428  }
2429  if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) {
2430  // OpenMP [2.16, Nesting of Regions]
2431  // distribute, parallel, parallel sections, parallel workshare, and the
2432  // parallel loop and parallel loop SIMD constructs are the only OpenMP
2433  // constructs that can be closely nested in the teams region.
2434  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2435  !isOpenMPDistributeDirective(CurrentRegion);
2436  Recommend = ShouldBeInParallelRegion;
2437  }
2438  if (!NestingProhibited && isOpenMPDistributeDirective(CurrentRegion)) {
2439  // OpenMP 4.5 [2.17 Nesting of Regions]
2440  // The region associated with the distribute construct must be strictly
2441  // nested inside a teams region
2442  NestingProhibited = !isOpenMPTeamsDirective(ParentRegion);
2443  Recommend = ShouldBeInTeamsRegion;
2444  }
2445  if (NestingProhibited) {
2446  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2447  << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend
2448  << getOpenMPDirectiveName(CurrentRegion);
2449  return true;
2450  }
2451  }
2452  return false;
2453 }
2454 
2456  ArrayRef<OMPClause *> Clauses,
2457  ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2458  bool ErrorFound = false;
2459  unsigned NamedModifiersNumber = 0;
2461  OMPD_unknown + 1);
2462  SmallVector<SourceLocation, 4> NameModifierLoc;
2463  for (const auto *C : Clauses) {
2464  if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2465  // At most one if clause without a directive-name-modifier can appear on
2466  // the directive.
2467  OpenMPDirectiveKind CurNM = IC->getNameModifier();
2468  if (FoundNameModifiers[CurNM]) {
2469  S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
2470  << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
2471  << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
2472  ErrorFound = true;
2473  } else if (CurNM != OMPD_unknown) {
2474  NameModifierLoc.push_back(IC->getNameModifierLoc());
2475  ++NamedModifiersNumber;
2476  }
2477  FoundNameModifiers[CurNM] = IC;
2478  if (CurNM == OMPD_unknown)
2479  continue;
2480  // Check if the specified name modifier is allowed for the current
2481  // directive.
2482  // At most one if clause with the particular directive-name-modifier can
2483  // appear on the directive.
2484  bool MatchFound = false;
2485  for (auto NM : AllowedNameModifiers) {
2486  if (CurNM == NM) {
2487  MatchFound = true;
2488  break;
2489  }
2490  }
2491  if (!MatchFound) {
2492  S.Diag(IC->getNameModifierLoc(),
2493  diag::err_omp_wrong_if_directive_name_modifier)
2495  ErrorFound = true;
2496  }
2497  }
2498  }
2499  // If any if clause on the directive includes a directive-name-modifier then
2500  // all if clauses on the directive must include a directive-name-modifier.
2501  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
2502  if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2503  S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
2504  diag::err_omp_no_more_if_clause);
2505  } else {
2506  std::string Values;
2507  std::string Sep(", ");
2508  unsigned AllowedCnt = 0;
2509  unsigned TotalAllowedNum =
2510  AllowedNameModifiers.size() - NamedModifiersNumber;
2511  for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
2512  ++Cnt) {
2513  OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
2514  if (!FoundNameModifiers[NM]) {
2515  Values += "'";
2516  Values += getOpenMPDirectiveName(NM);
2517  Values += "'";
2518  if (AllowedCnt + 2 == TotalAllowedNum)
2519  Values += " or ";
2520  else if (AllowedCnt + 1 != TotalAllowedNum)
2521  Values += Sep;
2522  ++AllowedCnt;
2523  }
2524  }
2525  S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
2526  diag::err_omp_unnamed_if_clause)
2527  << (TotalAllowedNum > 1) << Values;
2528  }
2529  for (auto Loc : NameModifierLoc) {
2530  S.Diag(Loc, diag::note_omp_previous_named_if_clause);
2531  }
2532  ErrorFound = true;
2533  }
2534  return ErrorFound;
2535 }
2536 
2538  OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
2539  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
2540  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
2541  StmtResult Res = StmtError();
2542  if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
2543  StartLoc))
2544  return StmtError();
2545 
2546  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
2547  llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
2548  bool ErrorFound = false;
2549  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2550  if (AStmt) {
2551  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
2552 
2553  // Check default data sharing attributes for referenced variables.
2554  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
2555  DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
2556  if (DSAChecker.isErrorFound())
2557  return StmtError();
2558  // Generate list of implicitly defined firstprivate variables.
2559  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2560 
2561  if (!DSAChecker.getImplicitFirstprivate().empty()) {
2562  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2563  DSAChecker.getImplicitFirstprivate(), SourceLocation(),
2565  ClausesWithImplicit.push_back(Implicit);
2566  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2567  DSAChecker.getImplicitFirstprivate().size();
2568  } else
2569  ErrorFound = true;
2570  }
2571  }
2572 
2573  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
2574  switch (Kind) {
2575  case OMPD_parallel:
2576  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
2577  EndLoc);
2578  AllowedNameModifiers.push_back(OMPD_parallel);
2579  break;
2580  case OMPD_simd:
2581  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2582  VarsWithInheritedDSA);
2583  break;
2584  case OMPD_for:
2585  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2586  VarsWithInheritedDSA);
2587  break;
2588  case OMPD_for_simd:
2589  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2590  EndLoc, VarsWithInheritedDSA);
2591  break;
2592  case OMPD_sections:
2593  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
2594  EndLoc);
2595  break;
2596  case OMPD_section:
2597  assert(ClausesWithImplicit.empty() &&
2598  "No clauses are allowed for 'omp section' directive");
2599  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
2600  break;
2601  case OMPD_single:
2602  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
2603  EndLoc);
2604  break;
2605  case OMPD_master:
2606  assert(ClausesWithImplicit.empty() &&
2607  "No clauses are allowed for 'omp master' directive");
2608  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
2609  break;
2610  case OMPD_critical:
2611  Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
2612  StartLoc, EndLoc);
2613  break;
2614  case OMPD_parallel_for:
2615  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
2616  EndLoc, VarsWithInheritedDSA);
2617  AllowedNameModifiers.push_back(OMPD_parallel);
2618  break;
2619  case OMPD_parallel_for_simd:
2621  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2622  AllowedNameModifiers.push_back(OMPD_parallel);
2623  break;
2624  case OMPD_parallel_sections:
2625  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
2626  StartLoc, EndLoc);
2627  AllowedNameModifiers.push_back(OMPD_parallel);
2628  break;
2629  case OMPD_task:
2630  Res =
2631  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2632  AllowedNameModifiers.push_back(OMPD_task);
2633  break;
2634  case OMPD_taskyield:
2635  assert(ClausesWithImplicit.empty() &&
2636  "No clauses are allowed for 'omp taskyield' directive");
2637  assert(AStmt == nullptr &&
2638  "No associated statement allowed for 'omp taskyield' directive");
2639  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
2640  break;
2641  case OMPD_barrier:
2642  assert(ClausesWithImplicit.empty() &&
2643  "No clauses are allowed for 'omp barrier' directive");
2644  assert(AStmt == nullptr &&
2645  "No associated statement allowed for 'omp barrier' directive");
2646  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
2647  break;
2648  case OMPD_taskwait:
2649  assert(ClausesWithImplicit.empty() &&
2650  "No clauses are allowed for 'omp taskwait' directive");
2651  assert(AStmt == nullptr &&
2652  "No associated statement allowed for 'omp taskwait' directive");
2653  Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
2654  break;
2655  case OMPD_taskgroup:
2656  assert(ClausesWithImplicit.empty() &&
2657  "No clauses are allowed for 'omp taskgroup' directive");
2658  Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc);
2659  break;
2660  case OMPD_flush:
2661  assert(AStmt == nullptr &&
2662  "No associated statement allowed for 'omp flush' directive");
2663  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
2664  break;
2665  case OMPD_ordered:
2666  Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
2667  EndLoc);
2668  break;
2669  case OMPD_atomic:
2670  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
2671  EndLoc);
2672  break;
2673  case OMPD_teams:
2674  Res =
2675  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2676  break;
2677  case OMPD_target:
2678  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
2679  EndLoc);
2680  AllowedNameModifiers.push_back(OMPD_target);
2681  break;
2682  case OMPD_cancellation_point:
2683  assert(ClausesWithImplicit.empty() &&
2684  "No clauses are allowed for 'omp cancellation point' directive");
2685  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
2686  "cancellation point' directive");
2687  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
2688  break;
2689  case OMPD_cancel:
2690  assert(AStmt == nullptr &&
2691  "No associated statement allowed for 'omp cancel' directive");
2692  Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
2693  CancelRegion);
2694  AllowedNameModifiers.push_back(OMPD_cancel);
2695  break;
2696  case OMPD_target_data:
2697  Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
2698  EndLoc);
2699  AllowedNameModifiers.push_back(OMPD_target_data);
2700  break;
2701  case OMPD_taskloop:
2702  Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
2703  EndLoc, VarsWithInheritedDSA);
2704  AllowedNameModifiers.push_back(OMPD_taskloop);
2705  break;
2706  case OMPD_taskloop_simd:
2707  Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2708  EndLoc, VarsWithInheritedDSA);
2709  AllowedNameModifiers.push_back(OMPD_taskloop);
2710  break;
2711  case OMPD_distribute:
2712  Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
2713  EndLoc, VarsWithInheritedDSA);
2714  break;
2715  case OMPD_threadprivate:
2716  llvm_unreachable("OpenMP Directive is not allowed");
2717  case OMPD_unknown:
2718  llvm_unreachable("Unknown OpenMP directive");
2719  }
2720 
2721  for (auto P : VarsWithInheritedDSA) {
2722  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
2723  << P.first << P.second->getSourceRange();
2724  }
2725  ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
2726 
2727  if (!AllowedNameModifiers.empty())
2728  ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
2729  ErrorFound;
2730 
2731  if (ErrorFound)
2732  return StmtError();
2733  return Res;
2734 }
2735 
2737  Stmt *AStmt,
2738  SourceLocation StartLoc,
2739  SourceLocation EndLoc) {
2740  if (!AStmt)
2741  return StmtError();
2742 
2743  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
2744  // 1.2.2 OpenMP Language Terminology
2745  // Structured block - An executable statement with a single entry at the
2746  // top and a single exit at the bottom.
2747  // The point of exit cannot be a branch out of the structured block.
2748  // longjmp() and throw() must not violate the entry/exit criteria.
2749  CS->getCapturedDecl()->setNothrow();
2750 
2752 
2753  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
2754  DSAStack->isCancelRegion());
2755 }
2756 
2757 namespace {
2758 /// \brief Helper class for checking canonical form of the OpenMP loops and
2759 /// extracting iteration space of each loop in the loop nest, that will be used
2760 /// for IR generation.
2761 class OpenMPIterationSpaceChecker {
2762  /// \brief Reference to Sema.
2763  Sema &SemaRef;
2764  /// \brief A location for diagnostics (when there is no some better location).
2765  SourceLocation DefaultLoc;
2766  /// \brief A location for diagnostics (when increment is not compatible).
2767  SourceLocation ConditionLoc;
2768  /// \brief A source location for referring to loop init later.
2769  SourceRange InitSrcRange;
2770  /// \brief A source location for referring to condition later.
2771  SourceRange ConditionSrcRange;
2772  /// \brief A source location for referring to increment later.
2773  SourceRange IncrementSrcRange;
2774  /// \brief Loop variable.
2775  VarDecl *Var;
2776  /// \brief Reference to loop variable.
2777  DeclRefExpr *VarRef;
2778  /// \brief Lower bound (initializer for the var).
2779  Expr *LB;
2780  /// \brief Upper bound.
2781  Expr *UB;
2782  /// \brief Loop step (increment).
2783  Expr *Step;
2784  /// \brief This flag is true when condition is one of:
2785  /// Var < UB
2786  /// Var <= UB
2787  /// UB > Var
2788  /// UB >= Var
2789  bool TestIsLessOp;
2790  /// \brief This flag is true when condition is strict ( < or > ).
2791  bool TestIsStrictOp;
2792  /// \brief This flag is true when step is subtracted on each iteration.
2793  bool SubtractStep;
2794 
2795 public:
2796  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
2797  : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc),
2798  InitSrcRange(SourceRange()), ConditionSrcRange(SourceRange()),
2799  IncrementSrcRange(SourceRange()), Var(nullptr), VarRef(nullptr),
2800  LB(nullptr), UB(nullptr), Step(nullptr), TestIsLessOp(false),
2801  TestIsStrictOp(false), SubtractStep(false) {}
2802  /// \brief Check init-expr for canonical loop form and save loop counter
2803  /// variable - #Var and its initialization value - #LB.
2804  bool CheckInit(Stmt *S, bool EmitDiags = true);
2805  /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
2806  /// for less/greater and for strict/non-strict comparison.
2807  bool CheckCond(Expr *S);
2808  /// \brief Check incr-expr for canonical loop form and return true if it
2809  /// does not conform, otherwise save loop step (#Step).
2810  bool CheckInc(Expr *S);
2811  /// \brief Return the loop counter variable.
2812  VarDecl *GetLoopVar() const { return Var; }
2813  /// \brief Return the reference expression to loop counter variable.
2814  DeclRefExpr *GetLoopVarRefExpr() const { return VarRef; }
2815  /// \brief Source range of the loop init.
2816  SourceRange GetInitSrcRange() const { return InitSrcRange; }
2817  /// \brief Source range of the loop condition.
2818  SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
2819  /// \brief Source range of the loop increment.
2820  SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
2821  /// \brief True if the step should be subtracted.
2822  bool ShouldSubtractStep() const { return SubtractStep; }
2823  /// \brief Build the expression to calculate the number of iterations.
2824  Expr *BuildNumIterations(Scope *S, const bool LimitedType) const;
2825  /// \brief Build the precondition expression for the loops.
2826  Expr *BuildPreCond(Scope *S, Expr *Cond) const;
2827  /// \brief Build reference expression to the counter be used for codegen.
2828  Expr *BuildCounterVar() const;
2829  /// \brief Build reference expression to the private counter be used for
2830  /// codegen.
2831  Expr *BuildPrivateCounterVar() const;
2832  /// \brief Build initization of the counter be used for codegen.
2833  Expr *BuildCounterInit() const;
2834  /// \brief Build step of the counter be used for codegen.
2835  Expr *BuildCounterStep() const;
2836  /// \brief Return true if any expression is dependent.
2837  bool Dependent() const;
2838 
2839 private:
2840  /// \brief Check the right-hand side of an assignment in the increment
2841  /// expression.
2842  bool CheckIncRHS(Expr *RHS);
2843  /// \brief Helper to set loop counter variable and its initializer.
2844  bool SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB);
2845  /// \brief Helper to set upper bound.
2846  bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
2847  SourceLocation SL);
2848  /// \brief Helper to set loop increment.
2849  bool SetStep(Expr *NewStep, bool Subtract);
2850 };
2851 
2852 bool OpenMPIterationSpaceChecker::Dependent() const {
2853  if (!Var) {
2854  assert(!LB && !UB && !Step);
2855  return false;
2856  }
2857  return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) ||
2858  (UB && UB->isValueDependent()) || (Step && Step->isValueDependent());
2859 }
2860 
2861 template <typename T>
2862 static T *getExprAsWritten(T *E) {
2863  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
2864  E = ExprTemp->getSubExpr();
2865 
2866  if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
2867  E = MTE->GetTemporaryExpr();
2868 
2869  while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
2870  E = Binder->getSubExpr();
2871 
2872  if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
2873  E = ICE->getSubExprAsWritten();
2874  return E->IgnoreParens();
2875 }
2876 
2877 bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar,
2878  DeclRefExpr *NewVarRefExpr,
2879  Expr *NewLB) {
2880  // State consistency checking to ensure correct usage.
2881  assert(Var == nullptr && LB == nullptr && VarRef == nullptr &&
2882  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
2883  if (!NewVar || !NewLB)
2884  return true;
2885  Var = NewVar;
2886  VarRef = NewVarRefExpr;
2887  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
2888  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
2889  if ((Ctor->isCopyOrMoveConstructor() ||
2890  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
2891  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
2892  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
2893  LB = NewLB;
2894  return false;
2895 }
2896 
2897 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
2898  SourceRange SR, SourceLocation SL) {
2899  // State consistency checking to ensure correct usage.
2900  assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr &&
2901  !TestIsLessOp && !TestIsStrictOp);
2902  if (!NewUB)
2903  return true;
2904  UB = NewUB;
2905  TestIsLessOp = LessOp;
2906  TestIsStrictOp = StrictOp;
2907  ConditionSrcRange = SR;
2908  ConditionLoc = SL;
2909  return false;
2910 }
2911 
2912 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
2913  // State consistency checking to ensure correct usage.
2914  assert(Var != nullptr && LB != nullptr && Step == nullptr);
2915  if (!NewStep)
2916  return true;
2917  if (!NewStep->isValueDependent()) {
2918  // Check that the step is integer expression.
2919  SourceLocation StepLoc = NewStep->getLocStart();
2920  ExprResult Val =
2921  SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
2922  if (Val.isInvalid())
2923  return true;
2924  NewStep = Val.get();
2925 
2926  // OpenMP [2.6, Canonical Loop Form, Restrictions]
2927  // If test-expr is of form var relational-op b and relational-op is < or
2928  // <= then incr-expr must cause var to increase on each iteration of the
2929  // loop. If test-expr is of form var relational-op b and relational-op is
2930  // > or >= then incr-expr must cause var to decrease on each iteration of
2931  // the loop.
2932  // If test-expr is of form b relational-op var and relational-op is < or
2933  // <= then incr-expr must cause var to decrease on each iteration of the
2934  // loop. If test-expr is of form b relational-op var and relational-op is
2935  // > or >= then incr-expr must cause var to increase on each iteration of
2936  // the loop.
2937  llvm::APSInt Result;
2938  bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
2939  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
2940  bool IsConstNeg =
2941  IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
2942  bool IsConstPos =
2943  IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
2944  bool IsConstZero = IsConstant && !Result.getBoolValue();
2945  if (UB && (IsConstZero ||
2946  (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
2947  : (IsConstPos || (IsUnsigned && !Subtract))))) {
2948  SemaRef.Diag(NewStep->getExprLoc(),
2949  diag::err_omp_loop_incr_not_compatible)
2950  << Var << TestIsLessOp << NewStep->getSourceRange();
2951  SemaRef.Diag(ConditionLoc,
2952  diag::note_omp_loop_cond_requres_compatible_incr)
2953  << TestIsLessOp << ConditionSrcRange;
2954  return true;
2955  }
2956  if (TestIsLessOp == Subtract) {
2957  NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus,
2958  NewStep).get();
2959  Subtract = !Subtract;
2960  }
2961  }
2962 
2963  Step = NewStep;
2964  SubtractStep = Subtract;
2965  return false;
2966 }
2967 
2968 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
2969  // Check init-expr for canonical loop form and save loop counter
2970  // variable - #Var and its initialization value - #LB.
2971  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
2972  // var = lb
2973  // integer-type var = lb
2974  // random-access-iterator-type var = lb
2975  // pointer-type var = lb
2976  //
2977  if (!S) {
2978  if (EmitDiags) {
2979  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
2980  }
2981  return true;
2982  }
2983  InitSrcRange = S->getSourceRange();
2984  if (Expr *E = dyn_cast<Expr>(S))
2985  S = E->IgnoreParens();
2986  if (auto BO = dyn_cast<BinaryOperator>(S)) {
2987  if (BO->getOpcode() == BO_Assign)
2988  if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens()))
2989  return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
2990  BO->getRHS());
2991  } else if (auto DS = dyn_cast<DeclStmt>(S)) {
2992  if (DS->isSingleDecl()) {
2993  if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
2994  if (Var->hasInit() && !Var->getType()->isReferenceType()) {
2995  // Accept non-canonical init form here but emit ext. warning.
2996  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
2997  SemaRef.Diag(S->getLocStart(),
2998  diag::ext_omp_loop_not_canonical_init)
2999  << S->getSourceRange();
3000  return SetVarAndLB(Var, nullptr, Var->getInit());
3001  }
3002  }
3003  }
3004  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S))
3005  if (CE->getOperator() == OO_Equal)
3006  if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0)))
3007  return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
3008  CE->getArg(1));
3009 
3010  if (EmitDiags) {
3011  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3012  << S->getSourceRange();
3013  }
3014  return true;
3015 }
3016 
3017 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
3018 /// variable (which may be the loop variable) if possible.
3019 static const VarDecl *GetInitVarDecl(const Expr *E) {
3020  if (!E)
3021  return nullptr;
3022  E = getExprAsWritten(E);
3023  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3024  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3025  if ((Ctor->isCopyOrMoveConstructor() ||
3026  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3027  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3028  E = CE->getArg(0)->IgnoreParenImpCasts();
3029  auto DRE = dyn_cast_or_null<DeclRefExpr>(E);
3030  if (!DRE)
3031  return nullptr;
3032  return dyn_cast<VarDecl>(DRE->getDecl());
3033 }
3034 
3035 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
3036  // Check test-expr for canonical form, save upper-bound UB, flags for
3037  // less/greater and for strict/non-strict comparison.
3038  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3039  // var relational-op b
3040  // b relational-op var
3041  //
3042  if (!S) {
3043  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var;
3044  return true;
3045  }
3046  S = getExprAsWritten(S);
3047  SourceLocation CondLoc = S->getLocStart();
3048  if (auto BO = dyn_cast<BinaryOperator>(S)) {
3049  if (BO->isRelationalOp()) {
3050  if (GetInitVarDecl(BO->getLHS()) == Var)
3051  return SetUB(BO->getRHS(),
3052  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3053  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3054  BO->getSourceRange(), BO->getOperatorLoc());
3055  if (GetInitVarDecl(BO->getRHS()) == Var)
3056  return SetUB(BO->getLHS(),
3057  (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3058  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3059  BO->getSourceRange(), BO->getOperatorLoc());
3060  }
3061  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3062  if (CE->getNumArgs() == 2) {
3063  auto Op = CE->getOperator();
3064  switch (Op) {
3065  case OO_Greater:
3066  case OO_GreaterEqual:
3067  case OO_Less:
3068  case OO_LessEqual:
3069  if (GetInitVarDecl(CE->getArg(0)) == Var)
3070  return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3071  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3072  CE->getOperatorLoc());
3073  if (GetInitVarDecl(CE->getArg(1)) == Var)
3074  return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3075  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3076  CE->getOperatorLoc());
3077  break;
3078  default:
3079  break;
3080  }
3081  }
3082  }
3083  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3084  << S->getSourceRange() << Var;
3085  return true;
3086 }
3087 
3088 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
3089  // RHS of canonical loop form increment can be:
3090  // var + incr
3091  // incr + var
3092  // var - incr
3093  //
3094  RHS = RHS->IgnoreParenImpCasts();
3095  if (auto BO = dyn_cast<BinaryOperator>(RHS)) {
3096  if (BO->isAdditiveOp()) {
3097  bool IsAdd = BO->getOpcode() == BO_Add;
3098  if (GetInitVarDecl(BO->getLHS()) == Var)
3099  return SetStep(BO->getRHS(), !IsAdd);
3100  if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var)
3101  return SetStep(BO->getLHS(), false);
3102  }
3103  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3104  bool IsAdd = CE->getOperator() == OO_Plus;
3105  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3106  if (GetInitVarDecl(CE->getArg(0)) == Var)
3107  return SetStep(CE->getArg(1), !IsAdd);
3108  if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var)
3109  return SetStep(CE->getArg(0), false);
3110  }
3111  }
3112  SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3113  << RHS->getSourceRange() << Var;
3114  return true;
3115 }
3116 
3117 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
3118  // Check incr-expr for canonical loop form and return true if it
3119  // does not conform.
3120  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3121  // ++var
3122  // var++
3123  // --var
3124  // var--
3125  // var += incr
3126  // var -= incr
3127  // var = var + incr
3128  // var = incr + var
3129  // var = var - incr
3130  //
3131  if (!S) {
3132  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var;
3133  return true;
3134  }
3135  IncrementSrcRange = S->getSourceRange();
3136  S = S->IgnoreParens();
3137  if (auto UO = dyn_cast<UnaryOperator>(S)) {
3138  if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var)
3139  return SetStep(
3140  SemaRef.ActOnIntegerConstant(UO->getLocStart(),
3141  (UO->isDecrementOp() ? -1 : 1)).get(),
3142  false);
3143  } else if (auto BO = dyn_cast<BinaryOperator>(S)) {
3144  switch (BO->getOpcode()) {
3145  case BO_AddAssign:
3146  case BO_SubAssign:
3147  if (GetInitVarDecl(BO->getLHS()) == Var)
3148  return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3149  break;
3150  case BO_Assign:
3151  if (GetInitVarDecl(BO->getLHS()) == Var)
3152  return CheckIncRHS(BO->getRHS());
3153  break;
3154  default:
3155  break;
3156  }
3157  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3158  switch (CE->getOperator()) {
3159  case OO_PlusPlus:
3160  case OO_MinusMinus:
3161  if (GetInitVarDecl(CE->getArg(0)) == Var)
3162  return SetStep(
3163  SemaRef.ActOnIntegerConstant(
3164  CE->getLocStart(),
3165  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(),
3166  false);
3167  break;
3168  case OO_PlusEqual:
3169  case OO_MinusEqual:
3170  if (GetInitVarDecl(CE->getArg(0)) == Var)
3171  return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3172  break;
3173  case OO_Equal:
3174  if (GetInitVarDecl(CE->getArg(0)) == Var)
3175  return CheckIncRHS(CE->getArg(1));
3176  break;
3177  default:
3178  break;
3179  }
3180  }
3181  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3182  << S->getSourceRange() << Var;
3183  return true;
3184 }
3185 
3186 namespace {
3187 // Transform variables declared in GNU statement expressions to new ones to
3188 // avoid crash on codegen.
3189 class TransformToNewDefs : public TreeTransform<TransformToNewDefs> {
3190  typedef TreeTransform<TransformToNewDefs> BaseTransform;
3191 
3192 public:
3193  TransformToNewDefs(Sema &SemaRef) : BaseTransform(SemaRef) {}
3194 
3195  Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
3196  if (auto *VD = cast<VarDecl>(D))
3197  if (!isa<ParmVarDecl>(D) && !isa<VarTemplateSpecializationDecl>(D) &&
3198  !isa<ImplicitParamDecl>(D)) {
3199  auto *NewVD = VarDecl::Create(
3200  SemaRef.Context, VD->getDeclContext(), VD->getLocStart(),
3201  VD->getLocation(), VD->getIdentifier(), VD->getType(),
3202  VD->getTypeSourceInfo(), VD->getStorageClass());
3203  NewVD->setTSCSpec(VD->getTSCSpec());
3204  NewVD->setInit(VD->getInit());
3205  NewVD->setInitStyle(VD->getInitStyle());
3206  NewVD->setExceptionVariable(VD->isExceptionVariable());
3207  NewVD->setNRVOVariable(VD->isNRVOVariable());
3208  NewVD->setCXXForRangeDecl(VD->isCXXForRangeDecl());
3209  NewVD->setConstexpr(VD->isConstexpr());
3210  NewVD->setInitCapture(VD->isInitCapture());
3211  NewVD->setPreviousDeclInSameBlockScope(
3213  VD->getDeclContext()->addHiddenDecl(NewVD);
3214  if (VD->hasAttrs())
3215  NewVD->setAttrs(VD->getAttrs());
3216  transformedLocalDecl(VD, NewVD);
3217  return NewVD;
3218  }
3219  return BaseTransform::TransformDefinition(Loc, D);
3220  }
3221 
3222  ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
3223  if (auto *NewD = TransformDecl(E->getExprLoc(), E->getDecl()))
3224  if (E->getDecl() != NewD) {
3225  NewD->setReferenced();
3226  NewD->markUsed(SemaRef.Context);
3227  return DeclRefExpr::Create(
3228  SemaRef.Context, E->getQualifierLoc(), E->getTemplateKeywordLoc(),
3229  cast<ValueDecl>(NewD), E->refersToEnclosingVariableOrCapture(),
3230  E->getNameInfo(), E->getType(), E->getValueKind());
3231  }
3232  return BaseTransform::TransformDeclRefExpr(E);
3233  }
3234 };
3235 }
3236 
3237 /// \brief Build the expression to calculate the number of iterations.
3238 Expr *
3239 OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
3240  const bool LimitedType) const {
3241  TransformToNewDefs Transform(SemaRef);
3242  ExprResult Diff;
3243  auto VarType = Var->getType().getNonReferenceType();
3244  if (VarType->isIntegerType() || VarType->isPointerType() ||
3245  SemaRef.getLangOpts().CPlusPlus) {
3246  // Upper - Lower
3247  auto *UBExpr = TestIsLessOp ? UB : LB;
3248  auto *LBExpr = TestIsLessOp ? LB : UB;
3249  Expr *Upper = Transform.TransformExpr(UBExpr).get();
3250  Expr *Lower = Transform.TransformExpr(LBExpr).get();
3251  if (!Upper || !Lower)
3252  return nullptr;
3253  if (!SemaRef.Context.hasSameType(Upper->getType(), UBExpr->getType())) {
3254  Upper = SemaRef
3255  .PerformImplicitConversion(Upper, UBExpr->getType(),
3257  /*AllowExplicit=*/true)
3258  .get();
3259  }
3260  if (!SemaRef.Context.hasSameType(Lower->getType(), LBExpr->getType())) {
3261  Lower = SemaRef
3262  .PerformImplicitConversion(Lower, LBExpr->getType(),
3264  /*AllowExplicit=*/true)
3265  .get();
3266  }
3267  if (!Upper || !Lower)
3268  return nullptr;
3269 
3270  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
3271 
3272  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
3273  // BuildBinOp already emitted error, this one is to point user to upper
3274  // and lower bound, and to tell what is passed to 'operator-'.
3275  SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
3276  << Upper->getSourceRange() << Lower->getSourceRange();
3277  return nullptr;
3278  }
3279  }
3280 
3281  if (!Diff.isUsable())
3282  return nullptr;
3283 
3284  // Upper - Lower [- 1]
3285  if (TestIsStrictOp)
3286  Diff = SemaRef.BuildBinOp(
3287  S, DefaultLoc, BO_Sub, Diff.get(),
3288  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3289  if (!Diff.isUsable())
3290  return nullptr;
3291 
3292  // Upper - Lower [- 1] + Step
3293  auto *StepNoImp = Step->IgnoreImplicit();
3294  auto NewStep = Transform.TransformExpr(StepNoImp);
3295  if (NewStep.isInvalid())
3296  return nullptr;
3297  if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
3298  StepNoImp->getType())) {
3299  NewStep = SemaRef.PerformImplicitConversion(
3300  NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
3301  /*AllowExplicit=*/true);
3302  if (NewStep.isInvalid())
3303  return nullptr;
3304  }
3305  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
3306  if (!Diff.isUsable())
3307  return nullptr;
3308 
3309  // Parentheses (for dumping/debugging purposes only).
3310  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
3311  if (!Diff.isUsable())
3312  return nullptr;
3313 
3314  // (Upper - Lower [- 1] + Step) / Step
3315  NewStep = Transform.TransformExpr(StepNoImp);
3316  if (NewStep.isInvalid())
3317  return nullptr;
3318  if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
3319  StepNoImp->getType())) {
3320  NewStep = SemaRef.PerformImplicitConversion(
3321  NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
3322  /*AllowExplicit=*/true);
3323  if (NewStep.isInvalid())
3324  return nullptr;
3325  }
3326  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
3327  if (!Diff.isUsable())
3328  return nullptr;
3329 
3330  // OpenMP runtime requires 32-bit or 64-bit loop variables.
3331  QualType Type = Diff.get()->getType();
3332  auto &C = SemaRef.Context;
3333  bool UseVarType = VarType->hasIntegerRepresentation() &&
3334  C.getTypeSize(Type) > C.getTypeSize(VarType);
3335  if (!Type->isIntegerType() || UseVarType) {
3336  unsigned NewSize =
3337  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
3338  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3340  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
3341  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
3342  Diff = SemaRef.PerformImplicitConversion(
3343  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
3344  if (!Diff.isUsable())
3345  return nullptr;
3346  }
3347  }
3348  if (LimitedType) {
3349  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
3350  if (NewSize != C.getTypeSize(Type)) {
3351  if (NewSize < C.getTypeSize(Type)) {
3352  assert(NewSize == 64 && "incorrect loop var size");
3353  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3354  << InitSrcRange << ConditionSrcRange;
3355  }
3356  QualType NewType = C.getIntTypeForBitwidth(
3357  NewSize, Type->hasSignedIntegerRepresentation() ||
3358  C.getTypeSize(Type) < NewSize);
3359  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
3360  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
3361  Sema::AA_Converting, true);
3362  if (!Diff.isUsable())
3363  return nullptr;
3364  }
3365  }
3366  }
3367 
3368  return Diff.get();
3369 }
3370 
3371 Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const {
3372  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
3373  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
3374  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
3375  TransformToNewDefs Transform(SemaRef);
3376 
3377  auto NewLB = Transform.TransformExpr(LB);
3378  auto NewUB = Transform.TransformExpr(UB);
3379  if (NewLB.isInvalid() || NewUB.isInvalid())
3380  return Cond;
3381  if (!SemaRef.Context.hasSameType(NewLB.get()->getType(), LB->getType())) {
3382  NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->getType(),
3384  /*AllowExplicit=*/true);
3385  }
3386  if (!SemaRef.Context.hasSameType(NewUB.get()->getType(), UB->getType())) {
3387  NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->getType(),
3389  /*AllowExplicit=*/true);
3390  }
3391  if (NewLB.isInvalid() || NewUB.isInvalid())
3392  return Cond;
3393  auto CondExpr = SemaRef.BuildBinOp(
3394  S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
3395  : (TestIsStrictOp ? BO_GT : BO_GE),
3396  NewLB.get(), NewUB.get());
3397  if (CondExpr.isUsable()) {
3398  if (!SemaRef.Context.hasSameType(CondExpr.get()->getType(),
3399  SemaRef.Context.BoolTy))
3400  CondExpr = SemaRef.PerformImplicitConversion(
3401  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
3402  /*AllowExplicit=*/true);
3403  }
3404  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
3405  // Otherwise use original loop conditon and evaluate it in runtime.
3406  return CondExpr.isUsable() ? CondExpr.get() : Cond;
3407 }
3408 
3409 /// \brief Build reference expression to the counter be used for codegen.
3410 Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const {
3411  return buildDeclRefExpr(SemaRef, Var, Var->getType().getNonReferenceType(),
3412  DefaultLoc);
3413 }
3414 
3415 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
3416  if (Var && !Var->isInvalidDecl()) {
3417  auto Type = Var->getType().getNonReferenceType();
3418  auto *PrivateVar =
3419  buildVarDecl(SemaRef, DefaultLoc, Type, Var->getName(),
3420  Var->hasAttrs() ? &Var->getAttrs() : nullptr);
3421  if (PrivateVar->isInvalidDecl())
3422  return nullptr;
3423  return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
3424  }
3425  return nullptr;
3426 }
3427 
3428 /// \brief Build initization of the counter be used for codegen.
3430 
3431 /// \brief Build step of the counter be used for codegen.
3432 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
3433 
3434 /// \brief Iteration space of a single for loop.
3435 struct LoopIterationSpace {
3436  /// \brief Condition of the loop.
3437  Expr *PreCond;
3438  /// \brief This expression calculates the number of iterations in the loop.
3439  /// It is always possible to calculate it before starting the loop.
3440  Expr *NumIterations;
3441  /// \brief The loop counter variable.
3442  Expr *CounterVar;
3443  /// \brief Private loop counter variable.
3444  Expr *PrivateCounterVar;
3445  /// \brief This is initializer for the initial value of #CounterVar.
3446  Expr *CounterInit;
3447  /// \brief This is step for the #CounterVar used to generate its update:
3448  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
3449  Expr *CounterStep;
3450  /// \brief Should step be subtracted?
3451  bool Subtract;
3452  /// \brief Source range of the loop init.
3453  SourceRange InitSrcRange;
3454  /// \brief Source range of the loop condition.
3455  SourceRange CondSrcRange;
3456  /// \brief Source range of the loop increment.
3457  SourceRange IncSrcRange;
3458 };
3459 
3460 } // namespace
3461 
3463  assert(getLangOpts().OpenMP && "OpenMP is not active.");
3464  assert(Init && "Expected loop in canonical form.");
3465  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
3466  if (AssociatedLoops > 0 &&
3467  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
3468  OpenMPIterationSpaceChecker ISC(*this, ForLoc);
3469  if (!ISC.CheckInit(Init, /*EmitDiags=*/false))
3470  DSAStack->addLoopControlVariable(ISC.GetLoopVar());
3471  DSAStack->setAssociatedLoops(AssociatedLoops - 1);
3472  }
3473 }
3474 
3475 /// \brief Called on a for stmt to check and extract its iteration space
3476 /// for further processing (such as collapsing).
3478  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
3479  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
3480  Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
3481  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
3482  LoopIterationSpace &ResultIterSpace) {
3483  // OpenMP [2.6, Canonical Loop Form]
3484  // for (init-expr; test-expr; incr-expr) structured-block
3485  auto For = dyn_cast_or_null<ForStmt>(S);
3486  if (!For) {
3487  SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
3488  << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
3489  << getOpenMPDirectiveName(DKind) << NestedLoopCount
3490  << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
3491  if (NestedLoopCount > 1) {
3492  if (CollapseLoopCountExpr && OrderedLoopCountExpr)
3493  SemaRef.Diag(DSA.getConstructLoc(),
3494  diag::note_omp_collapse_ordered_expr)
3495  << 2 << CollapseLoopCountExpr->getSourceRange()
3496  << OrderedLoopCountExpr->getSourceRange();
3497  else if (CollapseLoopCountExpr)
3498  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
3499  diag::note_omp_collapse_ordered_expr)
3500  << 0 << CollapseLoopCountExpr->getSourceRange();
3501  else
3502  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
3503  diag::note_omp_collapse_ordered_expr)
3504  << 1 << OrderedLoopCountExpr->getSourceRange();
3505  }
3506  return true;
3507  }
3508  assert(For->getBody());
3509 
3510  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
3511 
3512  // Check init.
3513  auto Init = For->getInit();
3514  if (ISC.CheckInit(Init)) {
3515  return true;
3516  }
3517 
3518  bool HasErrors = false;
3519 
3520  // Check loop variable's type.
3521  auto Var = ISC.GetLoopVar();
3522 
3523  // OpenMP [2.6, Canonical Loop Form]
3524  // Var is one of the following:
3525  // A variable of signed or unsigned integer type.
3526  // For C++, a variable of a random access iterator type.
3527  // For C, a variable of a pointer type.
3528  auto VarType = Var->getType().getNonReferenceType();
3529  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
3530  !VarType->isPointerType() &&
3531  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
3532  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
3533  << SemaRef.getLangOpts().CPlusPlus;
3534  HasErrors = true;
3535  }
3536 
3537  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a
3538  // Construct
3539  // The loop iteration variable(s) in the associated for-loop(s) of a for or
3540  // parallel for construct is (are) private.
3541  // The loop iteration variable in the associated for-loop of a simd construct
3542  // with just one associated for-loop is linear with a constant-linear-step
3543  // that is the increment of the associated for-loop.
3544  // Exclude loop var from the list of variables with implicitly defined data
3545  // sharing attributes.
3546  VarsWithImplicitDSA.erase(Var);
3547 
3548  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in
3549  // a Construct, C/C++].
3550  // The loop iteration variable in the associated for-loop of a simd construct
3551  // with just one associated for-loop may be listed in a linear clause with a
3552  // constant-linear-step that is the increment of the associated for-loop.
3553  // The loop iteration variable(s) in the associated for-loop(s) of a for or
3554  // parallel for construct may be listed in a private or lastprivate clause.
3555  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false);
3556  auto LoopVarRefExpr = ISC.GetLoopVarRefExpr();
3557  // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
3558  // declared in the loop and it is predetermined as a private.
3559  auto PredeterminedCKind =
3560  isOpenMPSimdDirective(DKind)
3561  ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
3562  : OMPC_private;
3563  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
3564  DVar.CKind != PredeterminedCKind) ||
3565  ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
3566  isOpenMPDistributeDirective(DKind)) &&
3567  !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
3568  DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
3569  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
3570  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
3571  << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
3572  << getOpenMPClauseName(PredeterminedCKind);
3573  if (DVar.RefExpr == nullptr)
3574  DVar.CKind = PredeterminedCKind;
3575  ReportOriginalDSA(SemaRef, &DSA, Var, DVar, /*IsLoopIterVar=*/true);
3576  HasErrors = true;
3577  } else if (LoopVarRefExpr != nullptr) {
3578  // Make the loop iteration variable private (for worksharing constructs),
3579  // linear (for simd directives with the only one associated loop) or
3580  // lastprivate (for simd directives with several collapsed or ordered
3581  // loops).
3582  if (DVar.CKind == OMPC_unknown)
3583  DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(),
3584  /*FromParent=*/false);
3585  DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind);
3586  }
3587 
3588  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
3589 
3590  // Check test-expr.
3591  HasErrors |= ISC.CheckCond(For->getCond());
3592 
3593  // Check incr-expr.
3594  HasErrors |= ISC.CheckInc(For->getInc());
3595 
3596  if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
3597  return HasErrors;
3598 
3599  // Build the loop's iteration space representation.
3600  ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond());
3601  ResultIterSpace.NumIterations = ISC.BuildNumIterations(
3602  DSA.getCurScope(), (isOpenMPWorksharingDirective(DKind) ||
3603  isOpenMPTaskLoopDirective(DKind) ||
3604  isOpenMPDistributeDirective(DKind)));
3605  ResultIterSpace.CounterVar = ISC.BuildCounterVar();
3606  ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
3607  ResultIterSpace.CounterInit = ISC.BuildCounterInit();
3608  ResultIterSpace.CounterStep = ISC.BuildCounterStep();
3609  ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
3610  ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
3611  ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
3612  ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
3613 
3614  HasErrors |= (ResultIterSpace.PreCond == nullptr ||
3615  ResultIterSpace.NumIterations == nullptr ||
3616  ResultIterSpace.CounterVar == nullptr ||
3617  ResultIterSpace.PrivateCounterVar == nullptr ||
3618  ResultIterSpace.CounterInit == nullptr ||
3619  ResultIterSpace.CounterStep == nullptr);
3620 
3621  return HasErrors;
3622 }
3623 
3624 /// \brief Build 'VarRef = Start.
3626  ExprResult VarRef, ExprResult Start) {
3627  TransformToNewDefs Transform(SemaRef);
3628  // Build 'VarRef = Start.
3629  auto *StartNoImp = Start.get()->IgnoreImplicit();
3630  auto NewStart = Transform.TransformExpr(StartNoImp);
3631  if (NewStart.isInvalid())
3632  return ExprError();
3633  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
3634  StartNoImp->getType())) {
3635  NewStart = SemaRef.PerformImplicitConversion(
3636  NewStart.get(), StartNoImp->getType(), Sema::AA_Converting,
3637  /*AllowExplicit=*/true);
3638  if (NewStart.isInvalid())
3639  return ExprError();
3640  }
3641  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
3642  VarRef.get()->getType())) {
3643  NewStart = SemaRef.PerformImplicitConversion(
3644  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
3645  /*AllowExplicit=*/true);
3646  if (!NewStart.isUsable())
3647  return ExprError();
3648  }
3649 
3650  auto Init =
3651  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
3652  return Init;
3653 }
3654 
3655 /// \brief Build 'VarRef = Start + Iter * Step'.
3657  SourceLocation Loc, ExprResult VarRef,
3658  ExprResult Start, ExprResult Iter,
3659  ExprResult Step, bool Subtract) {
3660  // Add parentheses (for debugging purposes only).
3661  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
3662  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
3663  !Step.isUsable())
3664  return ExprError();
3665 
3666  auto *StepNoImp = Step.get()->IgnoreImplicit();
3667  TransformToNewDefs Transform(SemaRef);
3668  auto NewStep = Transform.TransformExpr(StepNoImp);
3669  if (NewStep.isInvalid())
3670  return ExprError();
3671  if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
3672  StepNoImp->getType())) {
3673  NewStep = SemaRef.PerformImplicitConversion(
3674  NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
3675  /*AllowExplicit=*/true);
3676  if (NewStep.isInvalid())
3677  return ExprError();
3678  }
3679  ExprResult Update =
3680  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
3681  if (!Update.isUsable())
3682  return ExprError();
3683 
3684  // Build 'VarRef = Start + Iter * Step'.
3685  auto *StartNoImp = Start.get()->IgnoreImplicit();
3686  auto NewStart = Transform.TransformExpr(StartNoImp);
3687  if (NewStart.isInvalid())
3688  return ExprError();
3689  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
3690  StartNoImp->getType())) {
3691  NewStart = SemaRef.PerformImplicitConversion(
3692  NewStart.get(), StartNoImp->getType(), Sema::AA_Converting,
3693  /*AllowExplicit=*/true);
3694  if (NewStart.isInvalid())
3695  return ExprError();
3696  }
3697  Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add),
3698  NewStart.get(), Update.get());
3699  if (!Update.isUsable())
3700  return ExprError();
3701 
3702  Update = SemaRef.PerformImplicitConversion(
3703  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
3704  if (!Update.isUsable())
3705  return ExprError();
3706 
3707  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
3708  return Update;
3709 }
3710 
3711 /// \brief Convert integer expression \a E to make it have at least \a Bits
3712 /// bits.
3713 static ExprResult WidenIterationCount(unsigned Bits, Expr *E,
3714  Sema &SemaRef) {
3715  if (E == nullptr)
3716  return ExprError();
3717  auto &C = SemaRef.Context;
3718  QualType OldType = E->getType();
3719  unsigned HasBits = C.getTypeSize(OldType);
3720  if (HasBits >= Bits)
3721  return ExprResult(E);
3722  // OK to convert to signed, because new type has more bits than old.
3723  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
3724  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
3725  true);
3726 }
3727 
3728 /// \brief Check if the given expression \a E is a constant integer that fits
3729 /// into \a Bits bits.
3730 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
3731  if (E == nullptr)
3732  return false;
3733  llvm::APSInt Result;
3734  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
3735  return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
3736  return false;
3737 }
3738 
3739 /// \brief Called on a for stmt to check itself and nested loops (if any).
3740 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
3741 /// number of collapsed loops otherwise.
3742 static unsigned
3743 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
3744  Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
3745  DSAStackTy &DSA,
3746  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
3748  unsigned NestedLoopCount = 1;
3749  if (CollapseLoopCountExpr) {
3750  // Found 'collapse' clause - calculate collapse number.
3751  llvm::APSInt Result;
3752  if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
3753  NestedLoopCount = Result.getLimitedValue();
3754  }
3755  if (OrderedLoopCountExpr) {
3756  // Found 'ordered' clause - calculate collapse number.
3757  llvm::APSInt Result;
3758  if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
3759  if (Result.getLimitedValue() < NestedLoopCount) {
3760  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
3761  diag::err_omp_wrong_ordered_loop_count)
3762  << OrderedLoopCountExpr->getSourceRange();
3763  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
3764  diag::note_collapse_loop_count)
3765  << CollapseLoopCountExpr->getSourceRange();
3766  }
3767  NestedLoopCount = Result.getLimitedValue();
3768  }
3769  }
3770  // This is helper routine for loop directives (e.g., 'for', 'simd',
3771  // 'for simd', etc.).
3773  IterSpaces.resize(NestedLoopCount);
3774  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
3775  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
3776  if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
3777  NestedLoopCount, CollapseLoopCountExpr,
3778  OrderedLoopCountExpr, VarsWithImplicitDSA,
3779  IterSpaces[Cnt]))
3780  return 0;
3781  // Move on to the next nested for loop, or to the loop body.
3782  // OpenMP [2.8.1, simd construct, Restrictions]
3783  // All loops associated with the construct must be perfectly nested; that
3784  // is, there must be no intervening code nor any OpenMP directive between
3785  // any two loops.
3786  CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
3787  }
3788 
3789  Built.clear(/* size */ NestedLoopCount);
3790 
3791  if (SemaRef.CurContext->isDependentContext())
3792  return NestedLoopCount;
3793 
3794  // An example of what is generated for the following code:
3795  //
3796  // #pragma omp simd collapse(2) ordered(2)
3797  // for (i = 0; i < NI; ++i)
3798  // for (k = 0; k < NK; ++k)
3799  // for (j = J0; j < NJ; j+=2) {
3800  // <loop body>
3801  // }
3802  //
3803  // We generate the code below.
3804  // Note: the loop body may be outlined in CodeGen.
3805  // Note: some counters may be C++ classes, operator- is used to find number of
3806  // iterations and operator+= to calculate counter value.
3807  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
3808  // or i64 is currently supported).
3809  //
3810  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
3811  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
3812  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
3813  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
3814  // // similar updates for vars in clauses (e.g. 'linear')
3815  // <loop body (using local i and j)>
3816  // }
3817  // i = NI; // assign final values of counters
3818  // j = NJ;
3819  //
3820 
3821  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
3822  // the iteration counts of the collapsed for loops.
3823  // Precondition tests if there is at least one iteration (all conditions are
3824  // true).
3825  auto PreCond = ExprResult(IterSpaces[0].PreCond);
3826  auto N0 = IterSpaces[0].NumIterations;
3827  ExprResult LastIteration32 = WidenIterationCount(
3828  32 /* Bits */, SemaRef.PerformImplicitConversion(
3829  N0->IgnoreImpCasts(), N0->getType(),
3830  Sema::AA_Converting, /*AllowExplicit=*/true)
3831  .get(),
3832  SemaRef);
3833  ExprResult LastIteration64 = WidenIterationCount(
3834  64 /* Bits */, SemaRef.PerformImplicitConversion(
3835  N0->IgnoreImpCasts(), N0->getType(),
3836  Sema::AA_Converting, /*AllowExplicit=*/true)
3837  .get(),
3838  SemaRef);
3839 
3840  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
3841  return NestedLoopCount;
3842 
3843  auto &C = SemaRef.Context;
3844  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
3845 
3846  Scope *CurScope = DSA.getCurScope();
3847  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
3848  if (PreCond.isUsable()) {
3849  PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd,
3850  PreCond.get(), IterSpaces[Cnt].PreCond);
3851  }
3852  auto N = IterSpaces[Cnt].NumIterations;
3853  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
3854  if (LastIteration32.isUsable())
3855  LastIteration32 = SemaRef.BuildBinOp(
3856  CurScope, SourceLocation(), BO_Mul, LastIteration32.get(),
3857  SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
3859  /*AllowExplicit=*/true)
3860  .get());
3861  if (LastIteration64.isUsable())
3862  LastIteration64 = SemaRef.BuildBinOp(
3863  CurScope, SourceLocation(), BO_Mul, LastIteration64.get(),
3864  SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
3866  /*AllowExplicit=*/true)
3867  .get());
3868  }
3869 
3870  // Choose either the 32-bit or 64-bit version.
3871  ExprResult LastIteration = LastIteration64;
3872  if (LastIteration32.isUsable() &&
3873  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
3874  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
3875  FitsInto(
3876  32 /* Bits */,
3877  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
3878  LastIteration64.get(), SemaRef)))
3879  LastIteration = LastIteration32;
3880 
3881  if (!LastIteration.isUsable())
3882  return 0;
3883 
3884  // Save the number of iterations.
3885  ExprResult NumIterations = LastIteration;
3886  {
3887  LastIteration = SemaRef.BuildBinOp(
3888  CurScope, SourceLocation(), BO_Sub, LastIteration.get(),
3889  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3890  if (!LastIteration.isUsable())
3891  return 0;
3892  }
3893 
3894  // Calculate the last iteration number beforehand instead of doing this on
3895  // each iteration. Do not do this if the number of iterations may be kfold-ed.
3896  llvm::APSInt Result;
3897  bool IsConstant =
3898  LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
3899  ExprResult CalcLastIteration;
3900  if (!IsConstant) {
3901  SourceLocation SaveLoc;
3902  VarDecl *SaveVar =
3903  buildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(),
3904  ".omp.last.iteration");
3905  ExprResult SaveRef = buildDeclRefExpr(
3906  SemaRef, SaveVar, LastIteration.get()->getType(), SaveLoc);
3907  CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign,
3908  SaveRef.get(), LastIteration.get());
3909  LastIteration = SaveRef;
3910 
3911  // Prepare SaveRef + 1.
3912  NumIterations = SemaRef.BuildBinOp(
3913  CurScope, SaveLoc, BO_Add, SaveRef.get(),
3914  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3915  if (!NumIterations.isUsable())
3916  return 0;
3917  }
3918 
3919  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
3920 
3921  QualType VType = LastIteration.get()->getType();
3922  // Build variables passed into runtime, nesessary for worksharing directives.
3923  ExprResult LB, UB, IL, ST, EUB;
3925  isOpenMPDistributeDirective(DKind)) {
3926  // Lower bound variable, initialized with zero.
3927  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
3928  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
3929  SemaRef.AddInitializerToDecl(
3930  LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
3931  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
3932 
3933  // Upper bound variable, initialized with last iteration number.
3934  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
3935  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
3936  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
3937  /*DirectInit*/ false,
3938  /*TypeMayContainAuto*/ false);
3939 
3940  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
3941  // This will be used to implement clause 'lastprivate'.
3942  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
3943  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
3944  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
3945  SemaRef.AddInitializerToDecl(
3946  ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
3947  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
3948 
3949  // Stride variable returned by runtime (we initialize it to 1 by default).
3950  VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride");
3951  ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc);
3952  SemaRef.AddInitializerToDecl(
3953  STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
3954  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
3955 
3956  // Build expression: UB = min(UB, LastIteration)
3957  // It is nesessary for CodeGen of directives with static scheduling.
3958  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
3959  UB.get(), LastIteration.get());
3960  ExprResult CondOp = SemaRef.ActOnConditionalOp(
3961  InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
3962  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
3963  CondOp.get());
3964  EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
3965  }
3966 
3967  // Build the iteration variable and its initialization before loop.
3968  ExprResult IV;
3969  ExprResult Init;
3970  {
3971  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv");
3972  IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc);
3973  Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
3974  isOpenMPTaskLoopDirective(DKind) ||
3976  ? LB.get()
3977  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
3978  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
3979  Init = SemaRef.ActOnFinishFullExpr(Init.get());
3980  }
3981 
3982  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
3983  SourceLocation CondLoc;
3984  ExprResult Cond =
3985  (isOpenMPWorksharingDirective(DKind) ||
3987  ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
3988  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
3989  NumIterations.get());
3990 
3991  // Loop increment (IV = IV + 1)
3992  SourceLocation IncLoc;
3993  ExprResult Inc =
3994  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
3995  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
3996  if (!Inc.isUsable())
3997  return 0;
3998  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
3999  Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
4000  if (!Inc.isUsable())
4001  return 0;
4002 
4003  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
4004  // Used for directives with static scheduling.
4005  ExprResult NextLB, NextUB;
4007  isOpenMPDistributeDirective(DKind)) {
4008  // LB + ST
4009  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
4010  if (!NextLB.isUsable())
4011  return 0;
4012  // LB = LB + ST
4013  NextLB =
4014  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
4015  NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
4016  if (!NextLB.isUsable())
4017  return 0;
4018  // UB + ST
4019  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
4020  if (!NextUB.isUsable())
4021  return 0;
4022  // UB = UB + ST
4023  NextUB =
4024  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
4025  NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
4026  if (!NextUB.isUsable())
4027  return 0;
4028  }
4029 
4030  // Build updates and final values of the loop counters.
4031  bool HasErrors = false;
4032  Built.Counters.resize(NestedLoopCount);
4033  Built.Inits.resize(NestedLoopCount);
4034  Built.Updates.resize(NestedLoopCount);
4035  Built.Finals.resize(NestedLoopCount);
4036  {
4037  ExprResult Div;
4038  // Go from inner nested loop to outer.
4039  for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4040  LoopIterationSpace &IS = IterSpaces[Cnt];
4041  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
4042  // Build: Iter = (IV / Div) % IS.NumIters
4043  // where Div is product of previous iterations' IS.NumIters.
4044  ExprResult Iter;
4045  if (Div.isUsable()) {
4046  Iter =
4047  SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
4048  } else {
4049  Iter = IV;
4050  assert((Cnt == (int)NestedLoopCount - 1) &&
4051  "unusable div expected on first iteration only");
4052  }
4053 
4054  if (Cnt != 0 && Iter.isUsable())
4055  Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
4056  IS.NumIterations);
4057  if (!Iter.isUsable()) {
4058  HasErrors = true;
4059  break;
4060  }
4061 
4062  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
4063  auto *CounterVar = buildDeclRefExpr(
4064  SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()),
4065  IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
4066  /*RefersToCapture=*/true);
4067  ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
4068  IS.CounterInit);
4069  if (!Init.isUsable()) {
4070  HasErrors = true;
4071  break;
4072  }
4073  ExprResult Update =
4074  BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
4075  IS.CounterInit, Iter, IS.CounterStep, IS.Subtract);
4076  if (!Update.isUsable()) {
4077  HasErrors = true;
4078  break;
4079  }
4080 
4081  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
4083  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4084  IS.NumIterations, IS.CounterStep, IS.Subtract);
4085  if (!Final.isUsable()) {
4086  HasErrors = true;
4087  break;
4088  }
4089 
4090  // Build Div for the next iteration: Div <- Div * IS.NumIters
4091  if (Cnt != 0) {
4092  if (Div.isUnset())
4093  Div = IS.NumIterations;
4094  else
4095  Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
4096  IS.NumIterations);
4097 
4098  // Add parentheses (for debugging purposes only).
4099  if (Div.isUsable())
4100  Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get());
4101  if (!Div.isUsable()) {
4102  HasErrors = true;
4103  break;
4104  }
4105  }
4106  if (!Update.isUsable() || !Final.isUsable()) {
4107  HasErrors = true;
4108  break;
4109  }
4110  // Save results
4111  Built.Counters[Cnt] = IS.CounterVar;
4112  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
4113  Built.Inits[Cnt] = Init.get();
4114  Built.Updates[Cnt] = Update.get();
4115  Built.Finals[Cnt] = Final.get();
4116  }
4117  }
4118 
4119  if (HasErrors)
4120  return 0;
4121 
4122  // Save results
4123  Built.IterationVarRef = IV.get();
4124  Built.LastIteration = LastIteration.get();
4125  Built.NumIterations = NumIterations.get();
4126  Built.CalcLastIteration =
4127  SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
4128  Built.PreCond = PreCond.get();
4129  Built.Cond = Cond.get();
4130  Built.Init = Init.get();
4131  Built.Inc = Inc.get();
4132  Built.LB = LB.get();
4133  Built.UB = UB.get();
4134  Built.IL = IL.get();
4135  Built.ST = ST.get();
4136  Built.EUB = EUB.get();
4137  Built.NLB = NextLB.get();
4138  Built.NUB = NextUB.get();
4139 
4140  return NestedLoopCount;
4141 }
4142 
4144  auto CollapseClauses =
4145  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
4146  if (CollapseClauses.begin() != CollapseClauses.end())
4147  return (*CollapseClauses.begin())->getNumForLoops();
4148  return nullptr;
4149 }
4150 
4152  auto OrderedClauses =
4153  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
4154  if (OrderedClauses.begin() != OrderedClauses.end())
4155  return (*OrderedClauses.begin())->getNumForLoops();
4156  return nullptr;
4157 }
4158 
4159 static bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen,
4160  const Expr *Safelen) {
4161  llvm::APSInt SimdlenRes, SafelenRes;
4162  if (Simdlen->isValueDependent() || Simdlen->isTypeDependent() ||
4163  Simdlen->isInstantiationDependent() ||
4165  return false;
4166  if (Safelen->isValueDependent() || Safelen->isTypeDependent() ||
4167  Safelen->isInstantiationDependent() ||
4169  return false;
4170  Simdlen->EvaluateAsInt(SimdlenRes, S.Context);
4171  Safelen->EvaluateAsInt(SafelenRes, S.Context);
4172  // OpenMP 4.1 [2.8.1, simd Construct, Restrictions]
4173  // If both simdlen and safelen clauses are specified, the value of the simdlen
4174  // parameter must be less than or equal to the value of the safelen parameter.
4175  if (SimdlenRes > SafelenRes) {
4176  S.Diag(Simdlen->getExprLoc(), diag::err_omp_wrong_simdlen_safelen_values)
4177  << Simdlen->getSourceRange() << Safelen->getSourceRange();
4178  return true;
4179  }
4180  return false;
4181 }
4182 
4184  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4185  SourceLocation EndLoc,
4186  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4187  if (!AStmt)
4188  return StmtError();
4189 
4190  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4192  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4193  // define the nested loops number.
4194  unsigned NestedLoopCount = CheckOpenMPLoop(
4195  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
4196  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
4197  if (NestedLoopCount == 0)
4198  return StmtError();
4199 
4200  assert((CurContext->isDependentContext() || B.builtAll()) &&
4201  "omp simd loop exprs were not built");
4202 
4203  if (!CurContext->isDependentContext()) {
4204  // Finalize the clauses that need pre-built expressions for CodeGen.
4205  for (auto C : Clauses) {
4206  if (auto LC = dyn_cast<OMPLinearClause>(C))
4207  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4208  B.NumIterations, *this, CurScope))
4209  return StmtError();
4210  }
4211  }
4212 
4213  // OpenMP 4.1 [2.8.1, simd Construct, Restrictions]
4214  // If both simdlen and safelen clauses are specified, the value of the simdlen
4215  // parameter must be less than or equal to the value of the safelen parameter.
4216  OMPSafelenClause *Safelen = nullptr;
4217  OMPSimdlenClause *Simdlen = nullptr;
4218  for (auto *Clause : Clauses) {
4219  if (Clause->getClauseKind() == OMPC_safelen)
4220  Safelen = cast<OMPSafelenClause>(Clause);
4221  else if (Clause->getClauseKind() == OMPC_simdlen)
4222  Simdlen = cast<OMPSimdlenClause>(Clause);
4223  if (Safelen && Simdlen)
4224  break;
4225  }
4226  if (Simdlen && Safelen &&
4227  checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(),
4228  Safelen->getSafelen()))
4229  return StmtError();
4230 
4232  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
4233  Clauses, AStmt, B);
4234 }
4235 
4237  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4238  SourceLocation EndLoc,
4239  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4240  if (!AStmt)
4241  return StmtError();
4242 
4243  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4245  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4246  // define the nested loops number.
4247  unsigned NestedLoopCount = CheckOpenMPLoop(
4248  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
4249  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
4250  if (NestedLoopCount == 0)
4251  return StmtError();
4252 
4253  assert((CurContext->isDependentContext() || B.builtAll()) &&
4254  "omp for loop exprs were not built");
4255 
4256  if (!CurContext->isDependentContext()) {
4257  // Finalize the clauses that need pre-built expressions for CodeGen.
4258  for (auto C : Clauses) {
4259  if (auto LC = dyn_cast<OMPLinearClause>(C))
4260  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4261  B.NumIterations, *this, CurScope))
4262  return StmtError();
4263  }
4264  }
4265 
4267  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
4268  Clauses, AStmt, B, DSAStack->isCancelRegion());
4269 }
4270 
4272  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4273  SourceLocation EndLoc,
4274  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4275  if (!AStmt)
4276  return StmtError();
4277 
4278  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4280  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4281  // define the nested loops number.
4282  unsigned NestedLoopCount =
4283  CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
4284  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
4285  VarsWithImplicitDSA, B);
4286  if (NestedLoopCount == 0)
4287  return StmtError();
4288 
4289  assert((CurContext->isDependentContext() || B.builtAll()) &&
4290  "omp for simd loop exprs were not built");
4291 
4292  if (!CurContext->isDependentContext()) {
4293  // Finalize the clauses that need pre-built expressions for CodeGen.
4294  for (auto C : Clauses) {
4295  if (auto LC = dyn_cast<OMPLinearClause>(C))
4296  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4297  B.NumIterations, *this, CurScope))
4298  return StmtError();
4299  }
4300  }
4301 
4302  // OpenMP 4.1 [2.8.1, simd Construct, Restrictions]
4303  // If both simdlen and safelen clauses are specified, the value of the simdlen
4304  // parameter must be less than or equal to the value of the safelen parameter.
4305  OMPSafelenClause *Safelen = nullptr;
4306  OMPSimdlenClause *Simdlen = nullptr;
4307  for (auto *Clause : Clauses) {
4308  if (Clause->getClauseKind() == OMPC_safelen)
4309  Safelen = cast<OMPSafelenClause>(Clause);
4310  else if (Clause->getClauseKind() == OMPC_simdlen)
4311  Simdlen = cast<OMPSimdlenClause>(Clause);
4312  if (Safelen && Simdlen)
4313  break;
4314  }
4315  if (Simdlen && Safelen &&
4316  checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(),
4317  Safelen->getSafelen()))
4318  return StmtError();
4319 
4321  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
4322  Clauses, AStmt, B);
4323 }
4324 
4326  Stmt *AStmt,
4327  SourceLocation StartLoc,
4328  SourceLocation EndLoc) {
4329  if (!AStmt)
4330  return StmtError();
4331 
4332  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4333  auto BaseStmt = AStmt;
4334  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
4335  BaseStmt = CS->getCapturedStmt();
4336  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
4337  auto S = C->children();
4338  if (S.begin() == S.end())
4339  return StmtError();
4340  // All associated statements must be '#pragma omp section' except for
4341  // the first one.
4342  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
4343  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
4344  if (SectionStmt)
4345  Diag(SectionStmt->getLocStart(),
4346  diag::err_omp_sections_substmt_not_section);
4347  return StmtError();
4348  }
4349  cast<OMPSectionDirective>(SectionStmt)
4350  ->setHasCancel(DSAStack->isCancelRegion());
4351  }
4352  } else {
4353  Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
4354  return StmtError();
4355  }
4356 
4358 
4359  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
4360  DSAStack->isCancelRegion());
4361 }
4362 
4364  SourceLocation StartLoc,
4365  SourceLocation EndLoc) {
4366  if (!AStmt)
4367  return StmtError();
4368 
4369  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4370 
4372  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
4373 
4374  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
4375  DSAStack->isCancelRegion());
4376 }
4377 
4379  Stmt *AStmt,
4380  SourceLocation StartLoc,
4381  SourceLocation EndLoc) {
4382  if (!AStmt)
4383  return StmtError();
4384 
4385  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4386 
4388 
4389  // OpenMP [2.7.3, single Construct, Restrictions]
4390  // The copyprivate clause must not be used with the nowait clause.
4391  OMPClause *Nowait = nullptr;
4392  OMPClause *Copyprivate = nullptr;
4393  for (auto *Clause : Clauses) {
4394  if (Clause->getClauseKind() == OMPC_nowait)
4395  Nowait = Clause;
4396  else if (Clause->getClauseKind() == OMPC_copyprivate)
4397  Copyprivate = Clause;
4398  if (Copyprivate && Nowait) {
4399  Diag(Copyprivate->getLocStart(),
4400  diag::err_omp_single_copyprivate_with_nowait);
4401  Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
4402  return StmtError();
4403  }
4404  }
4405 
4406  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
4407 }
4408 
4410  SourceLocation StartLoc,
4411  SourceLocation EndLoc) {
4412  if (!AStmt)
4413  return StmtError();
4414 
4415  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4416 
4418 
4419  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
4420 }
4421 
4423  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
4424  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
4425  if (!AStmt)
4426  return StmtError();
4427 
4428  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4429 
4430  bool ErrorFound = false;
4431  llvm::APSInt Hint;
4432  SourceLocation HintLoc;
4433  bool DependentHint = false;
4434  for (auto *C : Clauses) {
4435  if (C->getClauseKind() == OMPC_hint) {
4436  if (!DirName.getName()) {
4437  Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
4438  ErrorFound = true;
4439  }
4440  Expr *E = cast<OMPHintClause>(C)->getHint();
4441  if (E->isTypeDependent() || E->isValueDependent() ||
4443  DependentHint = true;
4444  else {
4445  Hint = E->EvaluateKnownConstInt(Context);
4446  HintLoc = C->getLocStart();
4447  }
4448  }
4449  }
4450  if (ErrorFound)
4451  return StmtError();
4452  auto Pair = DSAStack->getCriticalWithHint(DirName);
4453  if (Pair.first && DirName.getName() && !DependentHint) {
4454  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
4455  Diag(StartLoc, diag::err_omp_critical_with_hint);
4456  if (HintLoc.isValid()) {
4457  Diag(HintLoc, diag::note_omp_critical_hint_here)
4458  << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
4459  } else
4460  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
4461  if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
4462  Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
4463  << 1
4464  << C->getHint()->EvaluateKnownConstInt(Context).toString(
4465  /*Radix=*/10, /*Signed=*/false);
4466  } else
4467  Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
4468  }
4469  }
4470 
4472 
4473  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
4474  Clauses, AStmt);
4475  if (!Pair.first && DirName.getName() && !DependentHint)
4476  DSAStack->addCriticalWithHint(Dir, Hint);
4477  return Dir;
4478 }
4479 
4481  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4482  SourceLocation EndLoc,
4483  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4484  if (!AStmt)
4485  return StmtError();
4486 
4487  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
4488  // 1.2.2 OpenMP Language Terminology
4489  // Structured block - An executable statement with a single entry at the
4490  // top and a single exit at the bottom.
4491  // The point of exit cannot be a branch out of the structured block.
4492  // longjmp() and throw() must not violate the entry/exit criteria.
4493  CS->getCapturedDecl()->setNothrow();
4494 
4496  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4497  // define the nested loops number.
4498  unsigned NestedLoopCount =
4499  CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
4500  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
4501  VarsWithImplicitDSA, B);
4502  if (NestedLoopCount == 0)
4503  return StmtError();
4504 
4505  assert((CurContext->isDependentContext() || B.builtAll()) &&
4506  "omp parallel for loop exprs were not built");
4507 
4508  if (!CurContext->isDependentContext()) {
4509  // Finalize the clauses that need pre-built expressions for CodeGen.
4510  for (auto C : Clauses) {
4511  if (auto LC = dyn_cast<OMPLinearClause>(C))
4512  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4513  B.NumIterations, *this, CurScope))
4514  return StmtError();
4515  }
4516  }
4517 
4519  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
4520  NestedLoopCount, Clauses, AStmt, B,
4521  DSAStack->isCancelRegion());
4522 }
4523 
4525  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
4526  SourceLocation EndLoc,
4527  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4528  if (!AStmt)
4529  return StmtError();
4530 
4531  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
4532  // 1.2.2 OpenMP Language Terminology
4533  // Structured block - An executable statement with a single entry at the
4534  // top and a single exit at the bottom.
4535  // The point of exit cannot be a branch out of the structured block.
4536  // longjmp() and throw() must not violate the entry/exit criteria.
4537  CS->getCapturedDecl()->setNothrow();
4538 
4540  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
4541  // define the nested loops number.
4542  unsigned NestedLoopCount =
4543  CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
4544  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
4545  VarsWithImplicitDSA, B);
4546  if (NestedLoopCount == 0)
4547  return StmtError();
4548 
4549  if (!CurContext->isDependentContext()) {
4550  // Finalize the clauses that need pre-built expressions for CodeGen.
4551  for (auto C : Clauses) {
4552  if (auto LC = dyn_cast<OMPLinearClause>(C))
4553  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
4554  B.NumIterations, *this, CurScope))
4555  return StmtError();
4556  }
4557  }
4558 
4559  // OpenMP 4.1 [2.8.1, simd Construct, Restrictions]
4560  // If both simdlen and safelen clauses are specified, the value of the simdlen
4561  // parameter must be less than or equal to the value of the safelen parameter.
4562  OMPSafelenClause *Safelen = nullptr;
4563  OMPSimdlenClause *Simdlen = nullptr;
4564  for (auto *Clause : Clauses) {
4565  if (Clause->getClauseKind() == OMPC_safelen)
4566  Safelen = cast<OMPSafelenClause>(Clause);
4567  else if (Clause->getClauseKind() == OMPC_simdlen)
4568  Simdlen = cast<OMPSimdlenClause>(Clause);
4569  if (Safelen && Simdlen)
4570  break;
4571  }
4572  if (Simdlen && Safelen &&
4573  checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(),
4574  Safelen->getSafelen()))
4575  return StmtError();
4576 
4579  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
4580 }
4581 
4582 StmtResult
4584  Stmt *AStmt, SourceLocation StartLoc,
4585  SourceLocation EndLoc) {
4586  if (!AStmt)
4587  return StmtError();
4588 
4589  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4590  auto BaseStmt = AStmt;
4591  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
4592  BaseStmt = CS->getCapturedStmt();
4593  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
4594  auto S = C->children();
4595  if (S.begin() == S.end())
4596  return StmtError();
4597  // All associated statements must be '#pragma omp section' except for
4598  // the first one.
4599  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
4600  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
4601  if (SectionStmt)
4602  Diag(SectionStmt->getLocStart(),
4603  diag::err_omp_parallel_sections_substmt_not_section);
4604  return StmtError();
4605  }
4606  cast<OMPSectionDirective>(SectionStmt)
4607  ->setHasCancel(DSAStack->isCancelRegion());
4608  }
4609  } else {
4610  Diag(AStmt->getLocStart(),
4611  diag::err_omp_parallel_sections_not_compound_stmt);
4612  return StmtError();
4613  }
4614 
4616 
4618  Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
4619 }
4620 
4622  Stmt *AStmt, SourceLocation StartLoc,
4623  SourceLocation EndLoc) {
4624  if (!AStmt)
4625  return StmtError();
4626 
4627  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
4628  // 1.2.2 OpenMP Language Terminology
4629  // Structured block - An executable statement with a single entry at the
4630  // top and a single exit at the bottom.
4631  // The point of exit cannot be a branch out of the structured block.
4632  // longjmp() and throw() must not violate the entry/exit criteria.
4633  CS->getCapturedDecl()->setNothrow();
4634 
4636 
4637  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
4638  DSAStack->isCancelRegion());
4639 }
4640 
4642  SourceLocation EndLoc) {
4643  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
4644 }
4645 
4647  SourceLocation EndLoc) {
4648  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
4649 }
4650 
4652  SourceLocation EndLoc) {
4653  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
4654 }
4655 
4657  SourceLocation StartLoc,
4658  SourceLocation EndLoc) {
4659  if (!AStmt)
4660  return StmtError();
4661 
4662  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4663 
4665 
4666  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt);
4667 }
4668 
4670  SourceLocation StartLoc,
4671  SourceLocation EndLoc) {
4672  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
4673  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
4674 }
4675 
4677  Stmt *AStmt,
4678  SourceLocation StartLoc,
4679  SourceLocation EndLoc) {
4680  OMPClause *DependFound = nullptr;
4681  OMPClause *DependSourceClause = nullptr;
4682  OMPClause *DependSinkClause = nullptr;
4683  bool ErrorFound = false;
4684  OMPThreadsClause *TC = nullptr;
4685  OMPSIMDClause *SC = nullptr;
4686  for (auto *C : Clauses) {
4687  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
4688  DependFound = C;
4689  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
4690  if (DependSourceClause) {
4691  Diag(C->getLocStart(), diag::err_omp_more_one_clause)
4692  << getOpenMPDirectiveName(OMPD_ordered)
4693  << getOpenMPClauseName(OMPC_depend) << 2;
4694  ErrorFound = true;
4695  } else
4696  DependSourceClause = C;
4697  if (DependSinkClause) {
4698  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
4699  << 0;
4700  ErrorFound = true;
4701  }
4702  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
4703  if (DependSourceClause) {
4704  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
4705  << 1;
4706  ErrorFound = true;
4707  }
4708  DependSinkClause = C;
4709  }
4710  } else if (C->getClauseKind() == OMPC_threads)
4711  TC = cast<OMPThreadsClause>(C);
4712  else if (C->getClauseKind() == OMPC_simd)
4713  SC = cast<OMPSIMDClause>(C);
4714  }
4715  if (!ErrorFound && !SC &&
4716  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
4717  // OpenMP [2.8.1,simd Construct, Restrictions]
4718  // An ordered construct with the simd clause is the only OpenMP construct
4719  // that can appear in the simd region.
4720  Diag(StartLoc, diag::err_omp_prohibited_region_simd);
4721  ErrorFound = true;
4722  } else if (DependFound && (TC || SC)) {
4723  Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
4724  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
4725  ErrorFound = true;
4726  } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) {
4727  Diag(DependFound->getLocStart(),
4728  diag::err_omp_ordered_directive_without_param);
4729  ErrorFound = true;
4730  } else if (TC || Clauses.empty()) {
4731  if (auto *Param = DSAStack->getParentOrderedRegionParam()) {
4732  SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
4733  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
4734  << (TC != nullptr);
4735  Diag(Param->getLocStart(), diag::note_omp_ordered_param);
4736  ErrorFound = true;
4737  }
4738  }
4739  if ((!AStmt && !DependFound) || ErrorFound)
4740  return StmtError();
4741 
4742  if (AStmt) {
4743  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4744 
4746  }
4747 
4748  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
4749 }
4750 
4751 namespace {
4752 /// \brief Helper class for checking expression in 'omp atomic [update]'
4753 /// construct.
4754 class OpenMPAtomicUpdateChecker {
4755  /// \brief Error results for atomic update expressions.
4756  enum ExprAnalysisErrorCode {
4757  /// \brief A statement is not an expression statement.
4758  NotAnExpression,
4759  /// \brief Expression is not builtin binary or unary operation.
4760  NotABinaryOrUnaryExpression,
4761  /// \brief Unary operation is not post-/pre- increment/decrement operation.
4762  NotAnUnaryIncDecExpression,
4763  /// \brief An expression is not of scalar type.
4764  NotAScalarType,
4765  /// \brief A binary operation is not an assignment operation.
4766  NotAnAssignmentOp,
4767  /// \brief RHS part of the binary operation is not a binary expression.
4768  NotABinaryExpression,
4769  /// \brief RHS part is not additive/multiplicative/shift/biwise binary
4770  /// expression.
4771  NotABinaryOperator,
4772  /// \brief RHS binary operation does not have reference to the updated LHS
4773  /// part.
4774  NotAnUpdateExpression,
4775  /// \brief No errors is found.
4776  NoError
4777  };
4778  /// \brief Reference to Sema.
4779  Sema &SemaRef;
4780  /// \brief A location for note diagnostics (when error is found).
4781  SourceLocation NoteLoc;
4782  /// \brief 'x' lvalue part of the source atomic expression.
4783  Expr *X;
4784  /// \brief 'expr' rvalue part of the source atomic expression.
4785  Expr *E;
4786  /// \brief Helper expression of the form
4787  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
4788  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
4789  Expr *UpdateExpr;
4790  /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
4791  /// important for non-associative operations.
4792  bool IsXLHSInRHSPart;
4793  BinaryOperatorKind Op;
4794  SourceLocation OpLoc;
4795  /// \brief true if the source expression is a postfix unary operation, false
4796  /// if it is a prefix unary operation.
4797  bool IsPostfixUpdate;
4798 
4799 public:
4800  OpenMPAtomicUpdateChecker(Sema &SemaRef)
4801  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
4802  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
4803  /// \brief Check specified statement that it is suitable for 'atomic update'
4804  /// constructs and extract 'x', 'expr' and Operation from the original
4805  /// expression. If DiagId and NoteId == 0, then only check is performed
4806  /// without error notification.
4807  /// \param DiagId Diagnostic which should be emitted if error is found.
4808  /// \param NoteId Diagnostic note for the main error message.
4809  /// \return true if statement is not an update expression, false otherwise.
4810  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
4811  /// \brief Return the 'x' lvalue part of the source atomic expression.
4812  Expr *getX() const { return X; }
4813  /// \brief Return the 'expr' rvalue part of the source atomic expression.
4814  Expr *getExpr() const { return E; }
4815  /// \brief Return the update expression used in calculation of the updated
4816  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
4817  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
4818  Expr *getUpdateExpr() const { return UpdateExpr; }
4819  /// \brief Return true if 'x' is LHS in RHS part of full update expression,
4820  /// false otherwise.
4821  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
4822 
4823  /// \brief true if the source expression is a postfix unary operation, false
4824  /// if it is a prefix unary operation.
4825  bool isPostfixUpdate() const { return IsPostfixUpdate; }
4826 
4827 private:
4828  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
4829  unsigned NoteId = 0);
4830 };
4831 } // namespace
4832 
4833 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
4834  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
4835  ExprAnalysisErrorCode ErrorFound = NoError;
4836  SourceLocation ErrorLoc, NoteLoc;
4837  SourceRange ErrorRange, NoteRange;
4838  // Allowed constructs are:
4839  // x = x binop expr;
4840  // x = expr binop x;
4841  if (AtomicBinOp->getOpcode() == BO_Assign) {
4842  X = AtomicBinOp->getLHS();
4843  if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
4844  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
4845  if (AtomicInnerBinOp->isMultiplicativeOp() ||
4846  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
4847  AtomicInnerBinOp->isBitwiseOp()) {
4848  Op = AtomicInnerBinOp->getOpcode();
4849  OpLoc = AtomicInnerBinOp->getOperatorLoc();
4850  auto *LHS = AtomicInnerBinOp->getLHS();
4851  auto *RHS = AtomicInnerBinOp->getRHS();
4852  llvm::FoldingSetNodeID XId, LHSId, RHSId;
4853  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
4854  /*Canonical=*/true);
4855  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
4856  /*Canonical=*/true);
4857  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
4858  /*Canonical=*/true);
4859  if (XId == LHSId) {
4860  E = RHS;
4861  IsXLHSInRHSPart = true;
4862  } else if (XId == RHSId) {
4863  E = LHS;
4864  IsXLHSInRHSPart = false;
4865  } else {
4866  ErrorLoc = AtomicInnerBinOp->getExprLoc();
4867  ErrorRange = AtomicInnerBinOp->getSourceRange();
4868  NoteLoc = X->getExprLoc();
4869  NoteRange = X->getSourceRange();
4870  ErrorFound = NotAnUpdateExpression;
4871  }
4872  } else {
4873  ErrorLoc = AtomicInnerBinOp->getExprLoc();
4874  ErrorRange = AtomicInnerBinOp->getSourceRange();
4875  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
4876  NoteRange = SourceRange(NoteLoc, NoteLoc);
4877  ErrorFound = NotABinaryOperator;
4878  }
4879  } else {
4880  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
4881  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
4882  ErrorFound = NotABinaryExpression;
4883  }
4884  } else {
4885  ErrorLoc = AtomicBinOp->getExprLoc();
4886  ErrorRange = AtomicBinOp->getSourceRange();
4887  NoteLoc = AtomicBinOp->getOperatorLoc();
4888  NoteRange = SourceRange(NoteLoc, NoteLoc);
4889  ErrorFound = NotAnAssignmentOp;
4890  }
4891  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
4892  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
4893  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
4894  return true;
4895  } else if (SemaRef.CurContext->isDependentContext())
4896  E = X = UpdateExpr = nullptr;
4897  return ErrorFound != NoError;
4898 }
4899 
4900 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
4901  unsigned NoteId) {
4902  ExprAnalysisErrorCode ErrorFound = NoError;
4903  SourceLocation ErrorLoc, NoteLoc;
4904  SourceRange ErrorRange, NoteRange;
4905  // Allowed constructs are:
4906  // x++;
4907  // x--;
4908  // ++x;
4909  // --x;
4910  // x binop= expr;
4911  // x = x binop expr;
4912  // x = expr binop x;
4913  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
4914  AtomicBody = AtomicBody->IgnoreParenImpCasts();
4915  if (AtomicBody->getType()->isScalarType() ||
4916  AtomicBody->isInstantiationDependent()) {
4917  if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
4918  AtomicBody->IgnoreParenImpCasts())) {
4919  // Check for Compound Assignment Operation
4921  AtomicCompAssignOp->getOpcode());
4922  OpLoc = AtomicCompAssignOp->getOperatorLoc();
4923  E = AtomicCompAssignOp->getRHS();
4924  X = AtomicCompAssignOp->getLHS();
4925  IsXLHSInRHSPart = true;
4926  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
4927  AtomicBody->IgnoreParenImpCasts())) {
4928  // Check for Binary Operation
4929  if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
4930  return true;
4931  } else if (auto *AtomicUnaryOp =
4932  dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) {
4933  // Check for Unary Operation
4934  if (AtomicUnaryOp->isIncrementDecrementOp()) {
4935  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
4936  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
4937  OpLoc = AtomicUnaryOp->getOperatorLoc();
4938  X = AtomicUnaryOp->getSubExpr();
4939  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
4940  IsXLHSInRHSPart = true;
4941  } else {
4942  ErrorFound = NotAnUnaryIncDecExpression;
4943  ErrorLoc = AtomicUnaryOp->getExprLoc();
4944  ErrorRange = AtomicUnaryOp->getSourceRange();
4945  NoteLoc = AtomicUnaryOp->getOperatorLoc();
4946  NoteRange = SourceRange(NoteLoc, NoteLoc);
4947  }
4948  } else if (!AtomicBody->isInstantiationDependent()) {
4949  ErrorFound = NotABinaryOrUnaryExpression;
4950  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
4951  NoteRange = ErrorRange = AtomicBody->getSourceRange();
4952  }
4953  } else {
4954  ErrorFound = NotAScalarType;
4955  NoteLoc = ErrorLoc = AtomicBody->getLocStart();
4956  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
4957  }
4958  } else {
4959  ErrorFound = NotAnExpression;
4960  NoteLoc = ErrorLoc = S->getLocStart();
4961  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
4962  }
4963  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
4964  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
4965  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
4966  return true;
4967  } else if (SemaRef.CurContext->isDependentContext())
4968  E = X = UpdateExpr = nullptr;
4969  if (ErrorFound == NoError && E && X) {
4970  // Build an update expression of form 'OpaqueValueExpr(x) binop
4971  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
4972  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
4973  auto *OVEX = new (SemaRef.getASTContext())
4974  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
4975  auto *OVEExpr = new (SemaRef.getASTContext())
4977  auto Update =
4978  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
4979  IsXLHSInRHSPart ? OVEExpr : OVEX);
4980  if (Update.isInvalid())
4981  return true;
4982  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
4984  if (Update.isInvalid())
4985  return true;
4986  UpdateExpr = Update.get();
4987  }
4988  return ErrorFound != NoError;
4989 }
4990 
4992  Stmt *AStmt,
4993  SourceLocation StartLoc,
4994  SourceLocation EndLoc) {
4995  if (!AStmt)
4996  return StmtError();
4997 
4998  auto CS = cast<CapturedStmt>(AStmt);
4999  // 1.2.2 OpenMP Language Terminology
5000  // Structured block - An executable statement with a single entry at the
5001  // top and a single exit at the bottom.
5002  // The point of exit cannot be a branch out of the structured block.
5003  // longjmp() and throw() must not violate the entry/exit criteria.
5004  OpenMPClauseKind AtomicKind = OMPC_unknown;
5005  SourceLocation AtomicKindLoc;
5006  for (auto *C : Clauses) {
5007  if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
5008  C->getClauseKind() == OMPC_update ||
5009  C->getClauseKind() == OMPC_capture) {
5010  if (AtomicKind != OMPC_unknown) {
5011  Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
5012  << SourceRange(C->getLocStart(), C->getLocEnd());
5013  Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
5014  << getOpenMPClauseName(AtomicKind);
5015  } else {
5016  AtomicKind = C->getClauseKind();
5017  AtomicKindLoc = C->getLocStart();
5018  }
5019  }
5020  }
5021 
5022  auto Body = CS->getCapturedStmt();
5023  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
5024  Body = EWC->getSubExpr();
5025 
5026  Expr *X = nullptr;
5027  Expr *V = nullptr;
5028  Expr *E = nullptr;
5029  Expr *UE = nullptr;
5030  bool IsXLHSInRHSPart = false;
5031  bool IsPostfixUpdate = false;
5032  // OpenMP [2.12.6, atomic Construct]
5033  // In the next expressions:
5034  // * x and v (as applicable) are both l-value expressions with scalar type.
5035  // * During the execution of an atomic region, multiple syntactic
5036  // occurrences of x must designate the same storage location.
5037  // * Neither of v and expr (as applicable) may access the storage location
5038  // designated by x.
5039  // * Neither of x and expr (as applicable) may access the storage location
5040  // designated by v.
5041  // * expr is an expression with scalar type.
5042  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
5043  // * binop, binop=, ++, and -- are not overloaded operators.
5044  // * The expression x binop expr must be numerically equivalent to x binop
5045  // (expr). This requirement is satisfied if the operators in expr have
5046  // precedence greater than binop, or by using parentheses around expr or
5047  // subexpressions of expr.
5048  // * The expression expr binop x must be numerically equivalent to (expr)
5049  // binop x. This requirement is satisfied if the operators in expr have
5050  // precedence equal to or greater than binop, or by using parentheses around
5051  // expr or subexpressions of expr.
5052  // * For forms that allow multiple occurrences of x, the number of times
5053  // that x is evaluated is unspecified.
5054  if (AtomicKind == OMPC_read) {
5055  enum {
5056  NotAnExpression,
5057  NotAnAssignmentOp,
5058  NotAScalarType,
5059  NotAnLValue,
5060  NoError
5061  } ErrorFound = NoError;
5062  SourceLocation ErrorLoc, NoteLoc;
5063  SourceRange ErrorRange, NoteRange;
5064  // If clause is read:
5065  // v = x;
5066  if (auto AtomicBody = dyn_cast<Expr>(Body)) {
5067  auto AtomicBinOp =
5068  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5069  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5070  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
5071  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
5072  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
5073  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
5074  if (!X->isLValue() || !V->isLValue()) {
5075  auto NotLValueExpr = X->isLValue() ? V : X;
5076  ErrorFound = NotAnLValue;
5077  ErrorLoc = AtomicBinOp->getExprLoc();
5078  ErrorRange = AtomicBinOp->getSourceRange();
5079  NoteLoc = NotLValueExpr->getExprLoc();
5080  NoteRange = NotLValueExpr->getSourceRange();
5081  }
5082  } else if (!X->isInstantiationDependent() ||
5083  !V->isInstantiationDependent()) {
5084  auto NotScalarExpr =
5086  ? V
5087  : X;
5088  ErrorFound = NotAScalarType;
5089  ErrorLoc = AtomicBinOp->getExprLoc();
5090  ErrorRange = AtomicBinOp->getSourceRange();
5091  NoteLoc = NotScalarExpr->getExprLoc();
5092  NoteRange = NotScalarExpr->getSourceRange();
5093  }
5094  } else if (!AtomicBody->isInstantiationDependent()) {
5095  ErrorFound = NotAnAssignmentOp;
5096  ErrorLoc = AtomicBody->getExprLoc();
5097  ErrorRange = AtomicBody->getSourceRange();
5098  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5099  : AtomicBody->getExprLoc();
5100  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5101  : AtomicBody->getSourceRange();
5102  }
5103  } else {
5104  ErrorFound = NotAnExpression;
5105  NoteLoc = ErrorLoc = Body->getLocStart();
5106  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5107  }
5108  if (ErrorFound != NoError) {
5109  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
5110  << ErrorRange;
5111  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5112  << NoteRange;
5113  return StmtError();
5114  } else if (CurContext->isDependentContext())
5115  V = X = nullptr;
5116  } else if (AtomicKind == OMPC_write) {
5117  enum {
5118  NotAnExpression,
5119  NotAnAssignmentOp,
5120  NotAScalarType,
5121  NotAnLValue,
5122  NoError
5123  } ErrorFound = NoError;
5124  SourceLocation ErrorLoc, NoteLoc;
5125  SourceRange ErrorRange, NoteRange;
5126  // If clause is write:
5127  // x = expr;
5128  if (auto AtomicBody = dyn_cast<Expr>(Body)) {
5129  auto AtomicBinOp =
5130  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5131  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5132  X = AtomicBinOp->getLHS();
5133  E = AtomicBinOp->getRHS();
5134  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
5135  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
5136  if (!X->isLValue()) {
5137  ErrorFound = NotAnLValue;
5138  ErrorLoc = AtomicBinOp->getExprLoc();
5139  ErrorRange = AtomicBinOp->getSourceRange();
5140  NoteLoc = X->getExprLoc();
5141  NoteRange = X->getSourceRange();
5142  }
5143  } else if (!X->isInstantiationDependent() ||
5144  !E->isInstantiationDependent()) {
5145  auto NotScalarExpr =
5147  ? E
5148  : X;
5149  ErrorFound = NotAScalarType;
5150  ErrorLoc = AtomicBinOp->getExprLoc();
5151  ErrorRange = AtomicBinOp->getSourceRange();
5152  NoteLoc = NotScalarExpr->getExprLoc();
5153  NoteRange = NotScalarExpr->getSourceRange();
5154  }
5155  } else if (!AtomicBody->isInstantiationDependent()) {
5156  ErrorFound = NotAnAssignmentOp;
5157  ErrorLoc = AtomicBody->getExprLoc();
5158  ErrorRange = AtomicBody->getSourceRange();
5159  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5160  : AtomicBody->getExprLoc();
5161  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5162  : AtomicBody->getSourceRange();
5163  }
5164  } else {
5165  ErrorFound = NotAnExpression;
5166  NoteLoc = ErrorLoc = Body->getLocStart();
5167  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5168  }
5169  if (ErrorFound != NoError) {
5170  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
5171  << ErrorRange;
5172  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5173  << NoteRange;
5174  return StmtError();
5175  } else if (CurContext->isDependentContext())
5176  E = X = nullptr;
5177  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
5178  // If clause is update:
5179  // x++;
5180  // x--;
5181  // ++x;
5182  // --x;
5183  // x binop= expr;
5184  // x = x binop expr;
5185  // x = expr binop x;
5186  OpenMPAtomicUpdateChecker Checker(*this);
5187  if (Checker.checkStatement(
5188  Body, (AtomicKind == OMPC_update)
5189  ? diag::err_omp_atomic_update_not_expression_statement
5190  : diag::err_omp_atomic_not_expression_statement,
5191  diag::note_omp_atomic_update))
5192  return StmtError();
5193  if (!CurContext->isDependentContext()) {
5194  E = Checker.getExpr();
5195  X = Checker.getX();
5196  UE = Checker.getUpdateExpr();
5197  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5198  }
5199  } else if (AtomicKind == OMPC_capture) {
5200  enum {
5201  NotAnAssignmentOp,
5202  NotACompoundStatement,
5203  NotTwoSubstatements,
5204  NotASpecificExpression,
5205  NoError
5206  } ErrorFound = NoError;
5207  SourceLocation ErrorLoc, NoteLoc;
5208  SourceRange ErrorRange, NoteRange;
5209  if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
5210  // If clause is a capture:
5211  // v = x++;
5212  // v = x--;
5213  // v = ++x;
5214  // v = --x;
5215  // v = x binop= expr;
5216  // v = x = x binop expr;
5217  // v = x = expr binop x;
5218  auto *AtomicBinOp =
5219  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5220  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5221  V = AtomicBinOp->getLHS();
5222  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
5223  OpenMPAtomicUpdateChecker Checker(*this);
5224  if (Checker.checkStatement(
5225  Body, diag::err_omp_atomic_capture_not_expression_statement,
5226  diag::note_omp_atomic_update))
5227  return StmtError();
5228  E = Checker.getExpr();
5229  X = Checker.getX();
5230  UE = Checker.getUpdateExpr();
5231  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5232  IsPostfixUpdate = Checker.isPostfixUpdate();
5233  } else if (!AtomicBody->isInstantiationDependent()) {
5234  ErrorLoc = AtomicBody->getExprLoc();
5235  ErrorRange = AtomicBody->getSourceRange();
5236  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5237  : AtomicBody->getExprLoc();
5238  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5239  : AtomicBody->getSourceRange();
5240  ErrorFound = NotAnAssignmentOp;
5241  }
5242  if (ErrorFound != NoError) {
5243  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
5244  << ErrorRange;
5245  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
5246  return StmtError();
5247  } else if (CurContext->isDependentContext()) {
5248  UE = V = E = X = nullptr;
5249  }
5250  } else {
5251  // If clause is a capture:
5252  // { v = x; x = expr; }
5253  // { v = x; x++; }
5254  // { v = x; x--; }
5255  // { v = x; ++x; }
5256  // { v = x; --x; }
5257  // { v = x; x binop= expr; }
5258  // { v = x; x = x binop expr; }
5259  // { v = x; x = expr binop x; }
5260  // { x++; v = x; }
5261  // { x--; v = x; }
5262  // { ++x; v = x; }
5263  // { --x; v = x; }
5264  // { x binop= expr; v = x; }
5265  // { x = x binop expr; v = x; }
5266  // { x = expr binop x; v = x; }
5267  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
5268  // Check that this is { expr1; expr2; }
5269  if (CS->size() == 2) {
5270  auto *First = CS->body_front();
5271  auto *Second = CS->body_back();
5272  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
5273  First = EWC->getSubExpr()->IgnoreParenImpCasts();
5274  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
5275  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
5276  // Need to find what subexpression is 'v' and what is 'x'.
5277  OpenMPAtomicUpdateChecker Checker(*this);
5278  bool IsUpdateExprFound = !Checker.checkStatement(Second);
5279  BinaryOperator *BinOp = nullptr;
5280  if (IsUpdateExprFound) {
5281  BinOp = dyn_cast<BinaryOperator>(First);
5282  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
5283  }
5284  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
5285  // { v = x; x++; }
5286  // { v = x; x--; }
5287  // { v = x; ++x; }
5288  // { v = x; --x; }
5289  // { v = x; x binop= expr; }
5290  // { v = x; x = x binop expr; }
5291  // { v = x; x = expr binop x; }
5292  // Check that the first expression has form v = x.
5293  auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
5294  llvm::FoldingSetNodeID XId, PossibleXId;
5295  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
5296  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
5297  IsUpdateExprFound = XId == PossibleXId;
5298  if (IsUpdateExprFound) {
5299  V = BinOp->getLHS();
5300  X = Checker.getX();
5301  E = Checker.getExpr();
5302  UE = Checker.getUpdateExpr();
5303  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5304  IsPostfixUpdate = true;
5305  }
5306  }
5307  if (!IsUpdateExprFound) {
5308  IsUpdateExprFound = !Checker.checkStatement(First);
5309  BinOp = nullptr;
5310  if (IsUpdateExprFound) {
5311  BinOp = dyn_cast<BinaryOperator>(Second);
5312  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
5313  }
5314  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
5315  // { x++; v = x; }
5316  // { x--; v = x; }
5317  // { ++x; v = x; }
5318  // { --x; v = x; }
5319  // { x binop= expr; v = x; }
5320  // { x = x binop expr; v = x; }
5321  // { x = expr binop x; v = x; }
5322  // Check that the second expression has form v = x.
5323  auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
5324  llvm::FoldingSetNodeID XId, PossibleXId;
5325  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
5326  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
5327  IsUpdateExprFound = XId == PossibleXId;
5328  if (IsUpdateExprFound) {
5329  V = BinOp->getLHS();
5330  X = Checker.getX();
5331  E = Checker.getExpr();
5332  UE = Checker.getUpdateExpr();
5333  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5334  IsPostfixUpdate = false;
5335  }
5336  }
5337  }
5338  if (!IsUpdateExprFound) {
5339  // { v = x; x = expr; }
5340  auto *FirstExpr = dyn_cast<Expr>(First);
5341  auto *SecondExpr = dyn_cast<Expr>(Second);
5342  if (!FirstExpr || !SecondExpr ||
5343  !(FirstExpr->isInstantiationDependent() ||
5344  SecondExpr->isInstantiationDependent())) {
5345  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
5346  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
5347  ErrorFound = NotAnAssignmentOp;
5348  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
5349  : First->getLocStart();
5350  NoteRange = ErrorRange = FirstBinOp
5351  ? FirstBinOp->getSourceRange()
5352  : SourceRange(ErrorLoc, ErrorLoc);
5353  } else {
5354  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
5355  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
5356  ErrorFound = NotAnAssignmentOp;
5357  NoteLoc = ErrorLoc = SecondBinOp
5358  ? SecondBinOp->getOperatorLoc()
5359  : Second->getLocStart();
5360  NoteRange = ErrorRange =
5361  SecondBinOp ? SecondBinOp->getSourceRange()
5362  : SourceRange(ErrorLoc, ErrorLoc);
5363  } else {
5364  auto *PossibleXRHSInFirst =
5365  FirstBinOp->getRHS()->IgnoreParenImpCasts();
5366  auto *PossibleXLHSInSecond =
5367  SecondBinOp->getLHS()->IgnoreParenImpCasts();
5368  llvm::FoldingSetNodeID X1Id, X2Id;
5369  PossibleXRHSInFirst->Profile(X1Id, Context,
5370  /*Canonical=*/true);
5371  PossibleXLHSInSecond->Profile(X2Id, Context,
5372  /*Canonical=*/true);
5373  IsUpdateExprFound = X1Id == X2Id;
5374  if (IsUpdateExprFound) {
5375  V = FirstBinOp->getLHS();
5376  X = SecondBinOp->getLHS();
5377  E = SecondBinOp->getRHS();
5378  UE = nullptr;
5379  IsXLHSInRHSPart = false;
5380  IsPostfixUpdate = true;
5381  } else {
5382  ErrorFound = NotASpecificExpression;
5383  ErrorLoc = FirstBinOp->getExprLoc();
5384  ErrorRange = FirstBinOp->getSourceRange();
5385  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
5386  NoteRange = SecondBinOp->getRHS()->getSourceRange();
5387  }
5388  }
5389  }
5390  }
5391  }
5392  } else {
5393  NoteLoc = ErrorLoc = Body->getLocStart();
5394  NoteRange = ErrorRange =
5395  SourceRange(Body->getLocStart(), Body->getLocStart());
5396  ErrorFound = NotTwoSubstatements;
5397  }
5398  } else {
5399  NoteLoc = ErrorLoc = Body->getLocStart();
5400  NoteRange = ErrorRange =
5401  SourceRange(Body->getLocStart(), Body->getLocStart());
5402  ErrorFound = NotACompoundStatement;
5403  }
5404  if (ErrorFound != NoError) {
5405  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
5406  << ErrorRange;
5407  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
5408  return StmtError();
5409  } else if (CurContext->isDependentContext()) {
5410  UE = V = E = X = nullptr;
5411  }
5412  }
5413  }
5414 
5416 
5417  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5418  X, V, E, UE, IsXLHSInRHSPart,
5419  IsPostfixUpdate);
5420 }
5421 
5423  Stmt *AStmt,
5424  SourceLocation StartLoc,
5425  SourceLocation EndLoc) {
5426  if (!AStmt)
5427  return StmtError();
5428 
5429  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5430  // 1.2.2 OpenMP Language Terminology
5431  // Structured block - An executable statement with a single entry at the
5432  // top and a single exit at the bottom.
5433  // The point of exit cannot be a branch out of the structured block.
5434  // longjmp() and throw() must not violate the entry/exit criteria.
5435  CS->getCapturedDecl()->setNothrow();
5436 
5437  // OpenMP [2.16, Nesting of Regions]
5438  // If specified, a teams construct must be contained within a target
5439  // construct. That target construct must contain no statements or directives
5440  // outside of the teams construct.
5441  if (DSAStack->hasInnerTeamsRegion()) {
5442  auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true);
5443  bool OMPTeamsFound = true;
5444  if (auto *CS = dyn_cast<CompoundStmt>(S)) {
5445  auto I = CS->body_begin();
5446  while (I != CS->body_end()) {
5447  auto OED = dyn_cast<OMPExecutableDirective>(*I);
5448  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
5449  OMPTeamsFound = false;
5450  break;
5451  }
5452  ++I;
5453  }
5454  assert(I != CS->body_end() && "Not found statement");
5455  S = *I;
5456  }
5457  if (!OMPTeamsFound) {
5458  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
5459  Diag(DSAStack->getInnerTeamsRegionLoc(),
5460  diag::note_omp_nested_teams_construct_here);
5461  Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
5462  << isa<OMPExecutableDirective>(S);
5463  return StmtError();
5464  }
5465  }
5466 
5468 
5469  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5470 }
5471 
5473  Stmt *AStmt,
5474  SourceLocation StartLoc,
5475  SourceLocation EndLoc) {
5476  if (!AStmt)
5477  return StmtError();
5478 
5479  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5480 
5482 
5483  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
5484  AStmt);
5485 }
5486 
5488  Stmt *AStmt, SourceLocation StartLoc,
5489  SourceLocation EndLoc) {
5490  if (!AStmt)
5491  return StmtError();
5492 
5493  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5494  // 1.2.2 OpenMP Language Terminology
5495  // Structured block - An executable statement with a single entry at the
5496  // top and a single exit at the bottom.
5497  // The point of exit cannot be a branch out of the structured block.
5498  // longjmp() and throw() must not violate the entry/exit criteria.
5499  CS->getCapturedDecl()->setNothrow();
5500 
5502 
5503  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5504 }
5505 
5506 StmtResult
5508  SourceLocation EndLoc,
5509  OpenMPDirectiveKind CancelRegion) {
5510  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
5511  CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
5512  Diag(StartLoc, diag::err_omp_wrong_cancel_region)
5513  << getOpenMPDirectiveName(CancelRegion);
5514  return StmtError();
5515  }
5516  if (DSAStack->isParentNowaitRegion()) {
5517  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
5518  return StmtError();
5519  }
5520  if (DSAStack->isParentOrderedRegion()) {
5521  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
5522  return StmtError();
5523  }
5524  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
5525  CancelRegion);
5526 }
5527 
5529  SourceLocation StartLoc,
5530  SourceLocation EndLoc,
5531  OpenMPDirectiveKind CancelRegion) {
5532  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
5533  CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
5534  Diag(StartLoc, diag::err_omp_wrong_cancel_region)
5535  << getOpenMPDirectiveName(CancelRegion);
5536  return StmtError();
5537  }
5538  if (DSAStack->isParentNowaitRegion()) {
5539  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
5540  return StmtError();
5541  }
5542  if (DSAStack->isParentOrderedRegion()) {
5543  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
5544  return StmtError();
5545  }
5546  DSAStack->setParentCancelRegion(/*Cancel=*/true);
5547  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
5548  CancelRegion);
5549 }
5550 
5552  ArrayRef<OMPClause *> Clauses) {
5553  OMPClause *PrevClause = nullptr;
5554  bool ErrorFound = false;
5555  for (auto *C : Clauses) {
5556  if (C->getClauseKind() == OMPC_grainsize ||
5557  C->getClauseKind() == OMPC_num_tasks) {
5558  if (!PrevClause)
5559  PrevClause = C;
5560  else if (PrevClause->getClauseKind() != C->getClauseKind()) {
5561  S.Diag(C->getLocStart(),
5562  diag::err_omp_grainsize_num_tasks_mutually_exclusive)
5563  << getOpenMPClauseName(C->getClauseKind())
5564  << getOpenMPClauseName(PrevClause->getClauseKind());
5565  S.Diag(PrevClause->getLocStart(),
5566  diag::note_omp_previous_grainsize_num_tasks)
5567  << getOpenMPClauseName(PrevClause->getClauseKind());
5568  ErrorFound = true;
5569  }
5570  }
5571  }
5572  return ErrorFound;
5573 }
5574 
5576  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5577  SourceLocation EndLoc,
5578  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
5579  if (!AStmt)
5580  return StmtError();
5581 
5582  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5584  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5585  // define the nested loops number.
5586  unsigned NestedLoopCount =
5587  CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
5588  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
5589  VarsWithImplicitDSA, B);
5590  if (NestedLoopCount == 0)
5591  return StmtError();
5592 
5593  assert((CurContext->isDependentContext() || B.builtAll()) &&
5594  "omp for loop exprs were not built");
5595 
5596  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
5597  // The grainsize clause and num_tasks clause are mutually exclusive and may
5598  // not appear on the same taskloop directive.
5599  if (checkGrainsizeNumTasksClauses(*this, Clauses))
5600  return StmtError();
5601 
5603  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
5604  NestedLoopCount, Clauses, AStmt, B);
5605 }
5606 
5608  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5609  SourceLocation EndLoc,
5610  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
5611  if (!AStmt)
5612  return StmtError();
5613 
5614  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5616  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5617  // define the nested loops number.
5618  unsigned NestedLoopCount =
5619  CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
5620  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
5621  VarsWithImplicitDSA, B);
5622  if (NestedLoopCount == 0)
5623  return StmtError();
5624 
5625  assert((CurContext->isDependentContext() || B.builtAll()) &&
5626  "omp for loop exprs were not built");
5627 
5628  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
5629  // The grainsize clause and num_tasks clause are mutually exclusive and may
5630  // not appear on the same taskloop directive.
5631  if (checkGrainsizeNumTasksClauses(*this, Clauses))
5632  return StmtError();
5633 
5635  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
5636  NestedLoopCount, Clauses, AStmt, B);
5637 }
5638 
5640  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5641  SourceLocation EndLoc,
5642  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
5643  if (!AStmt)
5644  return StmtError();
5645 
5646  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5648  // In presence of clause 'collapse' with number of loops, it will
5649  // define the nested loops number.
5650  unsigned NestedLoopCount =
5651  CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
5652  nullptr /*ordered not a clause on distribute*/, AStmt,
5653  *this, *DSAStack, VarsWithImplicitDSA, B);
5654  if (NestedLoopCount == 0)
5655  return StmtError();
5656 
5657  assert((CurContext->isDependentContext() || B.builtAll()) &&
5658  "omp for loop exprs were not built");
5659 
5661  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
5662  NestedLoopCount, Clauses, AStmt, B);
5663 }
5664 
5666  SourceLocation StartLoc,
5667  SourceLocation LParenLoc,
5668  SourceLocation EndLoc) {
5669  OMPClause *Res = nullptr;
5670  switch (Kind) {
5671  case OMPC_final:
5672  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
5673  break;
5674  case OMPC_num_threads:
5675  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
5676  break;
5677  case OMPC_safelen:
5678  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
5679  break;
5680  case OMPC_simdlen:
5681  Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
5682  break;
5683  case OMPC_collapse:
5684  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
5685  break;
5686  case OMPC_ordered:
5687  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
5688  break;
5689  case OMPC_device:
5690  Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
5691  break;
5692  case OMPC_num_teams:
5693  Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
5694  break;
5695  case OMPC_thread_limit:
5696  Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
5697  break;
5698  case OMPC_priority:
5699  Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
5700  break;
5701  case OMPC_grainsize:
5702  Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
5703  break;
5704  case OMPC_num_tasks:
5705  Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
5706  break;
5707  case OMPC_hint:
5708  Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
5709  break;
5710  case OMPC_if:
5711  case OMPC_default:
5712  case OMPC_proc_bind:
5713  case OMPC_schedule:
5714  case OMPC_private:
5715  case OMPC_firstprivate:
5716  case OMPC_lastprivate:
5717  case OMPC_shared:
5718  case OMPC_reduction:
5719  case OMPC_linear:
5720  case OMPC_aligned:
5721  case OMPC_copyin:
5722  case OMPC_copyprivate:
5723  case OMPC_nowait:
5724  case OMPC_untied:
5725  case OMPC_mergeable:
5726  case OMPC_threadprivate:
5727  case OMPC_flush:
5728  case OMPC_read:
5729  case OMPC_write:
5730  case OMPC_update:
5731  case OMPC_capture:
5732  case OMPC_seq_cst:
5733  case OMPC_depend:
5734  case OMPC_threads:
5735  case OMPC_simd:
5736  case OMPC_map:
5737  case OMPC_nogroup:
5738  case OMPC_unknown:
5739  llvm_unreachable("Clause is not allowed.");
5740  }
5741  return Res;
5742 }
5743 
5745  Expr *Condition, SourceLocation StartLoc,
5746  SourceLocation LParenLoc,
5747  SourceLocation NameModifierLoc,
5749  SourceLocation EndLoc) {
5750  Expr *ValExpr = Condition;
5751  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
5752  !Condition->isInstantiationDependent() &&
5753  !Condition->containsUnexpandedParameterPack()) {
5754  ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
5755  Condition->getExprLoc(), Condition);
5756  if (Val.isInvalid())
5757  return nullptr;
5758 
5759  ValExpr = Val.get();
5760  }
5761 
5762  return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,
5763  NameModifierLoc, ColonLoc, EndLoc);
5764 }
5765 
5767  SourceLocation StartLoc,
5768  SourceLocation LParenLoc,
5769  SourceLocation EndLoc) {
5770  Expr *ValExpr = Condition;
5771  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
5772  !Condition->isInstantiationDependent() &&
5773  !Condition->containsUnexpandedParameterPack()) {
5774  ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
5775  Condition->getExprLoc(), Condition);
5776  if (Val.isInvalid())
5777  return nullptr;
5778 
5779  ValExpr = Val.get();
5780  }
5781 
5782  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
5783 }
5785  Expr *Op) {
5786  if (!Op)
5787  return ExprError();
5788 
5789  class IntConvertDiagnoser : public ICEConvertDiagnoser {
5790  public:
5791  IntConvertDiagnoser()
5792  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
5793  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
5794  QualType T) override {
5795  return S.Diag(Loc, diag::err_omp_not_integral) << T;
5796  }
5797  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
5798  QualType T) override {
5799  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
5800  }
5801  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
5802  QualType T,
5803  QualType ConvTy) override {
5804  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
5805  }
5806  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
5807  QualType ConvTy) override {
5808  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
5809  << ConvTy->isEnumeralType() << ConvTy;
5810  }
5811  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
5812  QualType T) override {
5813  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
5814  }
5815  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
5816  QualType ConvTy) override {
5817  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
5818  << ConvTy->isEnumeralType() << ConvTy;
5819  }
5820  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
5821  QualType) override {
5822  llvm_unreachable("conversion functions are permitted");
5823  }
5824  } ConvertDiagnoser;
5825  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
5826 }
5827 
5828 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
5829  OpenMPClauseKind CKind,
5830  bool StrictlyPositive) {
5831  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
5832  !ValExpr->isInstantiationDependent()) {
5833  SourceLocation Loc = ValExpr->getExprLoc();
5834  ExprResult Value =
5835  SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
5836  if (Value.isInvalid())
5837  return false;
5838 
5839  ValExpr = Value.get();
5840  // The expression must evaluate to a non-negative integer value.
5841  llvm::APSInt Result;
5842  if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
5843  Result.isSigned() &&
5844  !((!StrictlyPositive && Result.isNonNegative()) ||
5845  (StrictlyPositive && Result.isStrictlyPositive()))) {
5846  SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
5847  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
5848  << ValExpr->getSourceRange();
5849  return false;
5850  }
5851  }
5852  return true;
5853 }
5854 
5856  SourceLocation StartLoc,
5857  SourceLocation LParenLoc,
5858  SourceLocation EndLoc) {
5859  Expr *ValExpr = NumThreads;
5860 
5861  // OpenMP [2.5, Restrictions]
5862  // The num_threads expression must evaluate to a positive integer value.
5863  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
5864  /*StrictlyPositive=*/true))
5865  return nullptr;
5866 
5867  return new (Context)
5868  OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
5869 }
5870 
5871 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
5872  OpenMPClauseKind CKind,
5873  bool StrictlyPositive) {
5874  if (!E)
5875  return ExprError();
5876  if (E->isValueDependent() || E->isTypeDependent() ||
5878  return E;
5879  llvm::APSInt Result;
5880  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
5881  if (ICE.isInvalid())
5882  return ExprError();
5883  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
5884  (!StrictlyPositive && !Result.isNonNegative())) {
5885  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
5886  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
5887  << E->getSourceRange();
5888  return ExprError();
5889  }
5890  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
5891  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
5892  << E->getSourceRange();
5893  return ExprError();
5894  }
5895  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
5896  DSAStack->setAssociatedLoops(Result.getExtValue());
5897  else if (CKind == OMPC_ordered)
5898  DSAStack->setAssociatedLoops(Result.getExtValue());
5899  return ICE;
5900 }
5901 
5903  SourceLocation LParenLoc,
5904  SourceLocation EndLoc) {
5905  // OpenMP [2.8.1, simd construct, Description]
5906  // The parameter of the safelen clause must be a constant
5907  // positive integer expression.
5908  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
5909  if (Safelen.isInvalid())
5910  return nullptr;
5911  return new (Context)
5912  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
5913 }
5914 
5916  SourceLocation LParenLoc,
5917  SourceLocation EndLoc) {
5918  // OpenMP [2.8.1, simd construct, Description]
5919  // The parameter of the simdlen clause must be a constant
5920  // positive integer expression.
5921  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
5922  if (Simdlen.isInvalid())
5923  return nullptr;
5924  return new (Context)
5925  OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
5926 }
5927 
5929  SourceLocation StartLoc,
5930  SourceLocation LParenLoc,
5931  SourceLocation EndLoc) {
5932  // OpenMP [2.7.1, loop construct, Description]
5933  // OpenMP [2.8.1, simd construct, Description]
5934  // OpenMP [2.9.6, distribute construct, Description]
5935  // The parameter of the collapse clause must be a constant
5936  // positive integer expression.
5937  ExprResult NumForLoopsResult =
5938  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
5939  if (NumForLoopsResult.isInvalid())
5940  return nullptr;
5941  return new (Context)
5942  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
5943 }
5944 
5946  SourceLocation EndLoc,
5947  SourceLocation LParenLoc,
5948  Expr *NumForLoops) {
5949  // OpenMP [2.7.1, loop construct, Description]
5950  // OpenMP [2.8.1, simd construct, Description]
5951  // OpenMP [2.9.6, distribute construct, Description]
5952  // The parameter of the ordered clause must be a constant
5953  // positive integer expression if any.
5954  if (NumForLoops && LParenLoc.isValid()) {
5955  ExprResult NumForLoopsResult =
5956  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
5957  if (NumForLoopsResult.isInvalid())
5958  return nullptr;
5959  NumForLoops = NumForLoopsResult.get();
5960  } else
5961  NumForLoops = nullptr;
5962  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops);
5963  return new (Context)
5964  OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc);
5965 }
5966 
5968  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
5969  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
5970  OMPClause *Res = nullptr;
5971  switch (Kind) {
5972  case OMPC_default:
5973  Res =
5974  ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
5975  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
5976  break;
5977  case OMPC_proc_bind:
5979  static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
5980  LParenLoc, EndLoc);
5981  break;
5982  case OMPC_if:
5983  case OMPC_final:
5984  case OMPC_num_threads:
5985  case OMPC_safelen:
5986  case OMPC_simdlen:
5987  case OMPC_collapse:
5988  case OMPC_schedule:
5989  case OMPC_private:
5990  case OMPC_firstprivate:
5991  case OMPC_lastprivate:
5992  case OMPC_shared:
5993  case OMPC_reduction:
5994  case OMPC_linear:
5995  case OMPC_aligned:
5996  case OMPC_copyin:
5997  case OMPC_copyprivate:
5998  case OMPC_ordered:
5999  case OMPC_nowait:
6000  case OMPC_untied:
6001  case OMPC_mergeable:
6002  case OMPC_threadprivate:
6003  case OMPC_flush:
6004  case OMPC_read:
6005  case OMPC_write:
6006  case OMPC_update:
6007  case OMPC_capture:
6008  case OMPC_seq_cst:
6009  case OMPC_depend:
6010  case OMPC_device:
6011  case OMPC_threads:
6012  case OMPC_simd:
6013  case OMPC_map:
6014  case OMPC_num_teams:
6015  case OMPC_thread_limit:
6016  case OMPC_priority:
6017  case OMPC_grainsize:
6018  case OMPC_nogroup:
6019  case OMPC_num_tasks:
6020  case OMPC_hint:
6021  case OMPC_unknown:
6022  llvm_unreachable("Clause is not allowed.");
6023  }
6024  return Res;
6025 }
6026 
6027 static std::string
6028 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
6029  ArrayRef<unsigned> Exclude = llvm::None) {
6030  std::string Values;
6031  unsigned Bound = Last >= 2 ? Last - 2 : 0;
6032  unsigned Skipped = Exclude.size();
6033  auto S = Exclude.begin(), E = Exclude.end();
6034  for (unsigned i = First; i < Last; ++i) {
6035  if (std::find(S, E, i) != E) {
6036  --Skipped;
6037  continue;
6038  }
6039  Values += "'";
6040  Values += getOpenMPSimpleClauseTypeName(K, i);
6041  Values += "'";
6042  if (i == Bound - Skipped)
6043  Values += " or ";
6044  else if (i != Bound + 1 - Skipped)
6045  Values += ", ";
6046  }
6047  return Values;
6048 }
6049 
6051  SourceLocation KindKwLoc,
6052  SourceLocation StartLoc,
6053  SourceLocation LParenLoc,
6054  SourceLocation EndLoc) {
6055  if (Kind == OMPC_DEFAULT_unknown) {
6056  static_assert(OMPC_DEFAULT_unknown > 0,
6057  "OMPC_DEFAULT_unknown not greater than 0");
6058  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
6059  << getListOfPossibleValues(OMPC_default, /*First=*/0,
6060  /*Last=*/OMPC_DEFAULT_unknown)
6061  << getOpenMPClauseName(OMPC_default);
6062  return nullptr;
6063  }
6064  switch (Kind) {
6065  case OMPC_DEFAULT_none:
6066  DSAStack->setDefaultDSANone(KindKwLoc);
6067  break;
6068  case OMPC_DEFAULT_shared:
6069  DSAStack->setDefaultDSAShared(KindKwLoc);
6070  break;
6071  case OMPC_DEFAULT_unknown:
6072  llvm_unreachable("Clause kind is not allowed.");
6073  break;
6074  }
6075  return new (Context)
6076  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
6077 }
6078 
6080  SourceLocation KindKwLoc,
6081  SourceLocation StartLoc,
6082  SourceLocation LParenLoc,
6083  SourceLocation EndLoc) {
6084  if (Kind == OMPC_PROC_BIND_unknown) {
6085  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
6086  << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
6087  /*Last=*/OMPC_PROC_BIND_unknown)
6088  << getOpenMPClauseName(OMPC_proc_bind);
6089  return nullptr;
6090  }
6091  return new (Context)
6092  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
6093 }
6094 
6096  OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
6097  SourceLocation StartLoc, SourceLocation LParenLoc,
6098  ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
6099  SourceLocation EndLoc) {
6100  OMPClause *Res = nullptr;
6101  switch (Kind) {
6102  case OMPC_schedule:
6103  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
6104  assert(Argument.size() == NumberOfElements &&
6105  ArgumentLoc.size() == NumberOfElements);
6107  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
6108  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
6109  static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
6110  StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
6111  ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
6112  break;
6113  case OMPC_if:
6114  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
6115  Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
6116  Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
6117  DelimLoc, EndLoc);
6118  break;
6119  case OMPC_final:
6120  case OMPC_num_threads:
6121  case OMPC_safelen:
6122  case OMPC_simdlen:
6123  case OMPC_collapse:
6124  case OMPC_default:
6125  case OMPC_proc_bind:
6126  case OMPC_private:
6127  case OMPC_firstprivate:
6128  case OMPC_lastprivate:
6129  case OMPC_shared:
6130  case OMPC_reduction:
6131  case OMPC_linear:
6132  case OMPC_aligned:
6133  case OMPC_copyin:
6134  case OMPC_copyprivate:
6135  case OMPC_ordered:
6136  case OMPC_nowait:
6137  case OMPC_untied:
6138  case OMPC_mergeable:
6139  case OMPC_threadprivate:
6140  case OMPC_flush:
6141  case OMPC_read:
6142  case OMPC_write:
6143  case OMPC_update:
6144  case OMPC_capture:
6145  case OMPC_seq_cst:
6146  case OMPC_depend:
6147  case OMPC_device:
6148  case OMPC_threads:
6149  case OMPC_simd:
6150  case OMPC_map:
6151  case OMPC_num_teams:
6152  case OMPC_thread_limit:
6153  case OMPC_priority:
6154  case OMPC_grainsize:
6155  case OMPC_nogroup:
6156  case OMPC_num_tasks:
6157  case OMPC_hint:
6158  case OMPC_unknown:
6159  llvm_unreachable("Clause is not allowed.");
6160  }
6161  return Res;
6162 }
6163 
6166  SourceLocation M1Loc, SourceLocation M2Loc) {
6167  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
6168  SmallVector<unsigned, 2> Excluded;
6170  Excluded.push_back(M2);
6171  if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
6172  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
6173  if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
6174  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
6175  S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
6176  << getListOfPossibleValues(OMPC_schedule,
6177  /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
6178  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
6179  Excluded)
6180  << getOpenMPClauseName(OMPC_schedule);
6181  return true;
6182  }
6183  return false;
6184 }
6185 
6188  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
6189  SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
6190  SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
6191  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
6192  checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
6193  return nullptr;
6194  // OpenMP, 2.7.1, Loop Construct, Restrictions
6195  // Either the monotonic modifier or the nonmonotonic modifier can be specified
6196  // but not both.
6197  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
6198  (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
6199  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
6200  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
6201  M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
6202  Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
6203  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
6204  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
6205  return nullptr;
6206  }
6207  if (Kind == OMPC_SCHEDULE_unknown) {
6208  std::string Values;
6209  if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
6210  unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
6211  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
6212  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
6213  Exclude);
6214  } else {
6215  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
6216  /*Last=*/OMPC_SCHEDULE_unknown);
6217  }
6218  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
6219  << Values << getOpenMPClauseName(OMPC_schedule);
6220  return nullptr;
6221  }
6222  // OpenMP, 2.7.1, Loop Construct, Restrictions
6223  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
6224  // schedule(guided).
6225  if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
6226  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
6227  Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
6228  Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
6229  diag::err_omp_schedule_nonmonotonic_static);
6230  return nullptr;
6231  }
6232  Expr *ValExpr = ChunkSize;
6233  Expr *HelperValExpr = nullptr;
6234  if (ChunkSize) {
6235  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
6236  !ChunkSize->isInstantiationDependent() &&
6237  !ChunkSize->containsUnexpandedParameterPack()) {
6238  SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
6239  ExprResult Val =
6240  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
6241  if (Val.isInvalid())
6242  return nullptr;
6243 
6244  ValExpr = Val.get();
6245 
6246  // OpenMP [2.7.1, Restrictions]
6247  // chunk_size must be a loop invariant integer expression with a positive
6248  // value.
6249  llvm::APSInt Result;
6250  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
6251  if (Result.isSigned() && !Result.isStrictlyPositive()) {
6252  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
6253  << "schedule" << 1 << ChunkSize->getSourceRange();
6254  return nullptr;
6255  }
6256  } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) {
6257  auto *ImpVar = buildVarDecl(*this, ChunkSize->getExprLoc(),
6258  ChunkSize->getType(), ".chunk.");
6259  auto *ImpVarRef = buildDeclRefExpr(*this, ImpVar, ChunkSize->getType(),
6260  ChunkSize->getExprLoc(),
6261  /*RefersToCapture=*/true);
6262  HelperValExpr = ImpVarRef;
6263  }
6264  }
6265  }
6266 
6267  return new (Context)
6268  OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
6269  ValExpr, HelperValExpr, M1, M1Loc, M2, M2Loc);
6270 }
6271 
6273  SourceLocation StartLoc,
6274  SourceLocation EndLoc) {
6275  OMPClause *Res = nullptr;
6276  switch (Kind) {
6277  case OMPC_ordered:
6278  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
6279  break;
6280  case OMPC_nowait:
6281  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
6282  break;
6283  case OMPC_untied:
6284  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
6285  break;
6286  case OMPC_mergeable:
6287  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
6288  break;
6289  case OMPC_read:
6290  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
6291  break;
6292  case OMPC_write:
6293  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
6294  break;
6295  case OMPC_update:
6296  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
6297  break;
6298  case OMPC_capture:
6299  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
6300  break;
6301  case OMPC_seq_cst:
6302  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
6303  break;
6304  case OMPC_threads:
6305  Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
6306  break;
6307  case OMPC_simd:
6308  Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
6309  break;
6310  case OMPC_nogroup:
6311  Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
6312  break;
6313  case OMPC_if:
6314  case OMPC_final:
6315  case OMPC_num_threads:
6316  case OMPC_safelen:
6317  case OMPC_simdlen:
6318  case OMPC_collapse:
6319  case OMPC_schedule:
6320  case OMPC_private:
6321  case OMPC_firstprivate:
6322  case OMPC_lastprivate:
6323  case OMPC_shared:
6324  case OMPC_reduction:
6325  case OMPC_linear:
6326  case OMPC_aligned:
6327  case OMPC_copyin:
6328  case OMPC_copyprivate:
6329  case OMPC_default:
6330  case OMPC_proc_bind:
6331  case OMPC_threadprivate:
6332  case OMPC_flush:
6333  case OMPC_depend:
6334  case OMPC_device:
6335  case OMPC_map:
6336  case OMPC_num_teams:
6337  case OMPC_thread_limit:
6338  case OMPC_priority:
6339  case OMPC_grainsize:
6340  case OMPC_num_tasks:
6341  case OMPC_hint:
6342  case OMPC_unknown:
6343  llvm_unreachable("Clause is not allowed.");
6344  }
6345  return Res;
6346 }
6347 
6349  SourceLocation EndLoc) {
6350  DSAStack->setNowaitRegion();
6351  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
6352 }
6353 
6355  SourceLocation EndLoc) {
6356  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
6357 }
6358 
6360  SourceLocation EndLoc) {
6361  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
6362 }
6363 
6365  SourceLocation EndLoc) {
6366  return new (Context) OMPReadClause(StartLoc, EndLoc);
6367 }
6368 
6370  SourceLocation EndLoc) {
6371  return new (Context) OMPWriteClause(StartLoc, EndLoc);
6372 }
6373 
6375  SourceLocation EndLoc) {
6376  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
6377 }
6378 
6380  SourceLocation EndLoc) {
6381  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
6382 }
6383 
6385  SourceLocation EndLoc) {
6386  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
6387 }
6388 
6390  SourceLocation EndLoc) {
6391  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
6392 }
6393 
6395  SourceLocation EndLoc) {
6396  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
6397 }
6398 
6400  SourceLocation EndLoc) {
6401  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
6402 }
6403 
6405  OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
6407  SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
6408  const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
6409  OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
6410  OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc) {
6411  OMPClause *Res = nullptr;
6412  switch (Kind) {
6413  case OMPC_private:
6414  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
6415  break;
6416  case OMPC_firstprivate:
6417  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
6418  break;
6419  case OMPC_lastprivate:
6420  Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
6421  break;
6422  case OMPC_shared:
6423  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
6424  break;
6425  case OMPC_reduction:
6426  Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
6427  EndLoc, ReductionIdScopeSpec, ReductionId);
6428  break;
6429  case OMPC_linear:
6430  Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
6431  LinKind, DepLinMapLoc, ColonLoc, EndLoc);
6432  break;
6433  case OMPC_aligned:
6434  Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
6435  ColonLoc, EndLoc);
6436  break;
6437  case OMPC_copyin:
6438  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
6439  break;
6440  case OMPC_copyprivate:
6441  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
6442  break;
6443  case OMPC_flush:
6444  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
6445  break;
6446  case OMPC_depend:
6447  Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
6448  StartLoc, LParenLoc, EndLoc);
6449  break;
6450  case OMPC_map:
6451  Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, DepLinMapLoc, ColonLoc,
6452  VarList, StartLoc, LParenLoc, EndLoc);
6453  break;
6454  case OMPC_if:
6455  case OMPC_final:
6456  case OMPC_num_threads:
6457  case OMPC_safelen:
6458  case OMPC_simdlen:
6459  case OMPC_collapse:
6460  case OMPC_default:
6461  case OMPC_proc_bind:
6462  case OMPC_schedule:
6463  case OMPC_ordered:
6464  case OMPC_nowait:
6465  case OMPC_untied:
6466  case OMPC_mergeable:
6467  case OMPC_threadprivate:
6468  case OMPC_read:
6469  case OMPC_write:
6470  case OMPC_update:
6471  case OMPC_capture:
6472  case OMPC_seq_cst:
6473  case OMPC_device:
6474  case OMPC_threads:
6475  case OMPC_simd:
6476  case OMPC_num_teams:
6477  case OMPC_thread_limit:
6478  case OMPC_priority:
6479  case OMPC_grainsize:
6480  case OMPC_nogroup:
6481  case OMPC_num_tasks:
6482  case OMPC_hint:
6483  case OMPC_unknown:
6484  llvm_unreachable("Clause is not allowed.");
6485  }
6486  return Res;
6487 }
6488 
6490  SourceLocation StartLoc,
6491  SourceLocation LParenLoc,
6492  SourceLocation EndLoc) {
6494  SmallVector<Expr *, 8> PrivateCopies;
6495  for (auto &RefExpr : VarList) {
6496  assert(RefExpr && "NULL expr in OpenMP private clause.");
6497  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6498  // It will be analyzed later.
6499  Vars.push_back(RefExpr);
6500  PrivateCopies.push_back(nullptr);
6501  continue;
6502  }
6503 
6504  SourceLocation ELoc = RefExpr->getExprLoc();
6505  // OpenMP [2.1, C/C++]
6506  // A list item is a variable name.
6507  // OpenMP [2.9.3.3, Restrictions, p.1]
6508  // A variable that is part of another variable (as an array or
6509  // structure element) cannot appear in a private clause.
6510  DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
6511  if (!DE || !isa<VarDecl>(DE->getDecl())) {
6512  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6513  continue;
6514  }
6515  Decl *D = DE->getDecl();
6516  VarDecl *VD = cast<VarDecl>(D);
6517 
6518  QualType Type = VD->getType();
6519  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6520  // It will be analyzed later.
6521  Vars.push_back(DE);
6522  PrivateCopies.push_back(nullptr);
6523  continue;
6524  }
6525 
6526  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
6527  // A variable that appears in a private clause must not have an incomplete
6528  // type or a reference type.
6529  if (RequireCompleteType(ELoc, Type,
6530  diag::err_omp_private_incomplete_type)) {
6531  continue;
6532  }
6533  Type = Type.getNonReferenceType();
6534 
6535  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
6536  // in a Construct]
6537  // Variables with the predetermined data-sharing attributes may not be
6538  // listed in data-sharing attributes clauses, except for the cases
6539  // listed below. For these exceptions only, listing a predetermined
6540  // variable in a data-sharing attribute clause is allowed and overrides
6541  // the variable's predetermined data-sharing attributes.
6542  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
6543  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
6544  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
6545  << getOpenMPClauseName(OMPC_private);
6546  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6547  continue;
6548  }
6549 
6550  // Variably modified types are not supported for tasks.
6551  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
6552  DSAStack->getCurrentDirective() == OMPD_task) {
6553  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
6554  << getOpenMPClauseName(OMPC_private) << Type
6555  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
6556  bool IsDecl =
6558  Diag(VD->getLocation(),
6559  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6560  << VD;
6561  continue;
6562  }
6563 
6564  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
6565  // A variable of class type (or array thereof) that appears in a private
6566  // clause requires an accessible, unambiguous default constructor for the
6567  // class type.
6568  // Generate helper private variable and initialize it with the default
6569  // value. The address of the original variable is replaced by the address of
6570  // the new private variable in CodeGen. This new variable is not added to
6571  // IdResolver, so the code in the OpenMP region uses original variable for
6572  // proper diagnostics.
6573  Type = Type.getUnqualifiedType();
6574  auto VDPrivate = buildVarDecl(*this, DE->getExprLoc(), Type, VD->getName(),
6575  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
6576  ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
6577  if (VDPrivate->isInvalidDecl())
6578  continue;
6579  auto VDPrivateRefExpr = buildDeclRefExpr(
6580  *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc());
6581 
6582  DSAStack->addDSA(VD, DE, OMPC_private);
6583  Vars.push_back(DE);
6584  PrivateCopies.push_back(VDPrivateRefExpr);
6585  }
6586 
6587  if (Vars.empty())
6588  return nullptr;
6589 
6590  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
6591  PrivateCopies);
6592 }
6593 
6594 namespace {
6595 class DiagsUninitializedSeveretyRAII {
6596 private:
6598  SourceLocation SavedLoc;
6599  bool IsIgnored;
6600 
6601 public:
6602  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
6603  bool IsIgnored)
6604  : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
6605  if (!IsIgnored) {
6606  Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
6607  /*Map*/ diag::Severity::Ignored, Loc);
6608  }
6609  }
6610  ~DiagsUninitializedSeveretyRAII() {
6611  if (!IsIgnored)
6612  Diags.popMappings(SavedLoc);
6613  }
6614 };
6615 }
6616 
6618  SourceLocation StartLoc,
6619  SourceLocation LParenLoc,
6620  SourceLocation EndLoc) {
6622  SmallVector<Expr *, 8> PrivateCopies;
6624  bool IsImplicitClause =
6625  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
6626  auto ImplicitClauseLoc = DSAStack->getConstructLoc();
6627 
6628  for (auto &RefExpr : VarList) {
6629  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
6630  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6631  // It will be analyzed later.
6632  Vars.push_back(RefExpr);
6633  PrivateCopies.push_back(nullptr);
6634  Inits.push_back(nullptr);
6635  continue;
6636  }
6637 
6638  SourceLocation ELoc =
6639  IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc();
6640  // OpenMP [2.1, C/C++]
6641  // A list item is a variable name.
6642  // OpenMP [2.9.3.3, Restrictions, p.1]
6643  // A variable that is part of another variable (as an array or
6644  // structure element) cannot appear in a private clause.
6645  DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
6646  if (!DE || !isa<VarDecl>(DE->getDecl())) {
6647  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6648  continue;
6649  }
6650  Decl *D = DE->getDecl();
6651  VarDecl *VD = cast<VarDecl>(D);
6652 
6653  QualType Type = VD->getType();
6654  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6655  // It will be analyzed later.
6656  Vars.push_back(DE);
6657  PrivateCopies.push_back(nullptr);
6658  Inits.push_back(nullptr);
6659  continue;
6660  }
6661 
6662  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
6663  // A variable that appears in a private clause must not have an incomplete
6664  // type or a reference type.
6665  if (RequireCompleteType(ELoc, Type,
6666  diag::err_omp_firstprivate_incomplete_type)) {
6667  continue;
6668  }
6669  Type = Type.getNonReferenceType();
6670 
6671  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
6672  // A variable of class type (or array thereof) that appears in a private
6673  // clause requires an accessible, unambiguous copy constructor for the
6674  // class type.
6675  auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
6676 
6677  // If an implicit firstprivate variable found it was checked already.
6678  if (!IsImplicitClause) {
6679  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
6680  bool IsConstant = ElemType.isConstant(Context);
6681  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
6682  // A list item that specifies a given variable may not appear in more
6683  // than one clause on the same directive, except that a variable may be
6684  // specified in both firstprivate and lastprivate clauses.
6685  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
6686  DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
6687  Diag(ELoc, diag::err_omp_wrong_dsa)
6688  << getOpenMPClauseName(DVar.CKind)
6689  << getOpenMPClauseName(OMPC_firstprivate);
6690  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6691  continue;
6692  }
6693 
6694  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
6695  // in a Construct]
6696  // Variables with the predetermined data-sharing attributes may not be
6697  // listed in data-sharing attributes clauses, except for the cases
6698  // listed below. For these exceptions only, listing a predetermined
6699  // variable in a data-sharing attribute clause is allowed and overrides
6700  // the variable's predetermined data-sharing attributes.
6701  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
6702  // in a Construct, C/C++, p.2]
6703  // Variables with const-qualified type having no mutable member may be
6704  // listed in a firstprivate clause, even if they are static data members.
6705  if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr &&
6706  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
6707  Diag(ELoc, diag::err_omp_wrong_dsa)
6708  << getOpenMPClauseName(DVar.CKind)
6709  << getOpenMPClauseName(OMPC_firstprivate);
6710  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6711  continue;
6712  }
6713 
6714  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
6715  // OpenMP [2.9.3.4, Restrictions, p.2]
6716  // A list item that is private within a parallel region must not appear
6717  // in a firstprivate clause on a worksharing construct if any of the
6718  // worksharing regions arising from the worksharing construct ever bind
6719  // to any of the parallel regions arising from the parallel construct.
6720  if (isOpenMPWorksharingDirective(CurrDir) &&
6721  !isOpenMPParallelDirective(CurrDir)) {
6722  DVar = DSAStack->getImplicitDSA(VD, true);
6723  if (DVar.CKind != OMPC_shared &&
6724  (isOpenMPParallelDirective(DVar.DKind) ||
6725  DVar.DKind == OMPD_unknown)) {
6726  Diag(ELoc, diag::err_omp_required_access)
6727  << getOpenMPClauseName(OMPC_firstprivate)
6728  << getOpenMPClauseName(OMPC_shared);
6729  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6730  continue;
6731  }
6732  }
6733  // OpenMP [2.9.3.4, Restrictions, p.3]
6734  // A list item that appears in a reduction clause of a parallel construct
6735  // must not appear in a firstprivate clause on a worksharing or task
6736  // construct if any of the worksharing or task regions arising from the
6737  // worksharing or task construct ever bind to any of the parallel regions
6738  // arising from the parallel construct.
6739  // OpenMP [2.9.3.4, Restrictions, p.4]
6740  // A list item that appears in a reduction clause in worksharing
6741  // construct must not appear in a firstprivate clause in a task construct
6742  // encountered during execution of any of the worksharing regions arising
6743  // from the worksharing construct.
6744  if (CurrDir == OMPD_task) {
6745  DVar =
6746  DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
6747  [](OpenMPDirectiveKind K) -> bool {
6748  return isOpenMPParallelDirective(K) ||
6750  },
6751  false);
6752  if (DVar.CKind == OMPC_reduction &&
6753  (isOpenMPParallelDirective(DVar.DKind) ||
6754  isOpenMPWorksharingDirective(DVar.DKind))) {
6755  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
6756  << getOpenMPDirectiveName(DVar.DKind);
6757  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6758  continue;
6759  }
6760  }
6761 
6762  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
6763  // A list item that is private within a teams region must not appear in a
6764  // firstprivate clause on a distribute construct if any of the distribute
6765  // regions arising from the distribute construct ever bind to any of the
6766  // teams regions arising from the teams construct.
6767  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
6768  // A list item that appears in a reduction clause of a teams construct
6769  // must not appear in a firstprivate clause on a distribute construct if
6770  // any of the distribute regions arising from the distribute construct
6771  // ever bind to any of the teams regions arising from the teams construct.
6772  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
6773  // A list item may appear in a firstprivate or lastprivate clause but not
6774  // both.
6775  if (CurrDir == OMPD_distribute) {
6776  DVar = DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_private),
6777  [](OpenMPDirectiveKind K) -> bool {
6778  return isOpenMPTeamsDirective(K);
6779  },
6780  false);
6781  if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) {
6782  Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams);
6783  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6784  continue;
6785  }
6786  DVar = DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
6787  [](OpenMPDirectiveKind K) -> bool {
6788  return isOpenMPTeamsDirective(K);
6789  },
6790  false);
6791  if (DVar.CKind == OMPC_reduction &&
6792  isOpenMPTeamsDirective(DVar.DKind)) {
6793  Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction);
6794  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6795  continue;
6796  }
6797  DVar = DSAStack->getTopDSA(VD, false);
6798  if (DVar.CKind == OMPC_lastprivate) {
6799  Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
6800  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6801  continue;
6802  }
6803  }
6804  }
6805 
6806  // Variably modified types are not supported for tasks.
6807  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
6808  DSAStack->getCurrentDirective() == OMPD_task) {
6809  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
6810  << getOpenMPClauseName(OMPC_firstprivate) << Type
6811  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
6812  bool IsDecl =
6814  Diag(VD->getLocation(),
6815  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6816  << VD;
6817  continue;
6818  }
6819 
6820  Type = Type.getUnqualifiedType();
6821  auto VDPrivate = buildVarDecl(*this, ELoc, Type, VD->getName(),
6822  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
6823  // Generate helper private variable and initialize it with the value of the
6824  // original variable. The address of the original variable is replaced by
6825  // the address of the new private variable in the CodeGen. This new variable
6826  // is not added to IdResolver, so the code in the OpenMP region uses
6827  // original variable for proper diagnostics and variable capturing.
6828  Expr *VDInitRefExpr = nullptr;
6829  // For arrays generate initializer for single element and replace it by the
6830  // original array element in CodeGen.
6831  if (Type->isArrayType()) {
6832  auto VDInit =
6833  buildVarDecl(*this, DE->getExprLoc(), ElemType, VD->getName());
6834  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
6835  auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
6836  ElemType = ElemType.getUnqualifiedType();
6837  auto *VDInitTemp = buildVarDecl(*this, DE->getLocStart(), ElemType,
6838  ".firstprivate.temp");
6839  InitializedEntity Entity =
6842 
6843  InitializationSequence InitSeq(*this, Entity, Kind, Init);
6844  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
6845  if (Result.isInvalid())
6846  VDPrivate->setInvalidDecl();
6847  else
6848  VDPrivate->setInit(Result.getAs<Expr>());
6849  // Remove temp variable declaration.
6850  Context.Deallocate(VDInitTemp);
6851  } else {
6852  auto *VDInit =
6853  buildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp");
6854  VDInitRefExpr =
6855  buildDeclRefExpr(*this, VDInit, DE->getType(), DE->getExprLoc());
6856  AddInitializerToDecl(VDPrivate,
6857  DefaultLvalueConversion(VDInitRefExpr).get(),
6858  /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
6859  }
6860  if (VDPrivate->isInvalidDecl()) {
6861  if (IsImplicitClause) {
6862  Diag(DE->getExprLoc(),
6863  diag::note_omp_task_predetermined_firstprivate_here);
6864  }
6865  continue;
6866  }
6867  CurContext->addDecl(VDPrivate);
6868  auto VDPrivateRefExpr = buildDeclRefExpr(
6869  *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc());
6870  DSAStack->addDSA(VD, DE, OMPC_firstprivate);
6871  Vars.push_back(DE);
6872  PrivateCopies.push_back(VDPrivateRefExpr);
6873  Inits.push_back(VDInitRefExpr);
6874  }
6875 
6876  if (Vars.empty())
6877  return nullptr;
6878 
6879  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
6880  Vars, PrivateCopies, Inits);
6881 }
6882 
6884  SourceLocation StartLoc,
6885  SourceLocation LParenLoc,
6886  SourceLocation EndLoc) {
6888  SmallVector<Expr *, 8> SrcExprs;
6889  SmallVector<Expr *, 8> DstExprs;
6890  SmallVector<Expr *, 8> AssignmentOps;
6891  for (auto &RefExpr : VarList) {
6892  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
6893  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6894  // It will be analyzed later.
6895  Vars.push_back(RefExpr);
6896  SrcExprs.push_back(nullptr);
6897  DstExprs.push_back(nullptr);
6898  AssignmentOps.push_back(nullptr);
6899  continue;
6900  }
6901 
6902  SourceLocation ELoc = RefExpr->getExprLoc();
6903  // OpenMP [2.1, C/C++]
6904  // A list item is a variable name.
6905  // OpenMP [2.14.3.5, Restrictions, p.1]
6906  // A variable that is part of another variable (as an array or structure
6907  // element) cannot appear in a lastprivate clause.
6908  DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
6909  if (!DE || !isa<VarDecl>(DE->getDecl())) {
6910  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6911  continue;
6912  }
6913  Decl *D = DE->getDecl();
6914  VarDecl *VD = cast<VarDecl>(D);
6915 
6916  QualType Type = VD->getType();
6917  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6918  // It will be analyzed later.
6919  Vars.push_back(DE);
6920  SrcExprs.push_back(nullptr);
6921  DstExprs.push_back(nullptr);
6922  AssignmentOps.push_back(nullptr);
6923  continue;
6924  }
6925 
6926  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
6927  // A variable that appears in a lastprivate clause must not have an
6928  // incomplete type or a reference type.
6929  if (RequireCompleteType(ELoc, Type,
6930  diag::err_omp_lastprivate_incomplete_type)) {
6931  continue;
6932  }
6933  Type = Type.getNonReferenceType();
6934 
6935  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
6936  // in a Construct]
6937  // Variables with the predetermined data-sharing attributes may not be
6938  // listed in data-sharing attributes clauses, except for the cases
6939  // listed below.
6940  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
6941  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
6942  DVar.CKind != OMPC_firstprivate &&
6943  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
6944  Diag(ELoc, diag::err_omp_wrong_dsa)
6945  << getOpenMPClauseName(DVar.CKind)
6946  << getOpenMPClauseName(OMPC_lastprivate);
6947  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6948  continue;
6949  }
6950 
6951  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
6952  // OpenMP [2.14.3.5, Restrictions, p.2]
6953  // A list item that is private within a parallel region, or that appears in
6954  // the reduction clause of a parallel construct, must not appear in a
6955  // lastprivate clause on a worksharing construct if any of the corresponding
6956  // worksharing regions ever binds to any of the corresponding parallel
6957  // regions.
6958  DSAStackTy::DSAVarData TopDVar = DVar;
6959  if (isOpenMPWorksharingDirective(CurrDir) &&
6960  !isOpenMPParallelDirective(CurrDir)) {
6961  DVar = DSAStack->getImplicitDSA(VD, true);
6962  if (DVar.CKind != OMPC_shared) {
6963  Diag(ELoc, diag::err_omp_required_access)
6964  << getOpenMPClauseName(OMPC_lastprivate)
6965  << getOpenMPClauseName(OMPC_shared);
6966  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6967  continue;
6968  }
6969  }
6970  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
6971  // A variable of class type (or array thereof) that appears in a
6972  // lastprivate clause requires an accessible, unambiguous default
6973  // constructor for the class type, unless the list item is also specified
6974  // in a firstprivate clause.
6975  // A variable of class type (or array thereof) that appears in a
6976  // lastprivate clause requires an accessible, unambiguous copy assignment
6977  // operator for the class type.
6979  auto *SrcVD = buildVarDecl(*this, DE->getLocStart(),
6980  Type.getUnqualifiedType(), ".lastprivate.src",
6981  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
6982  auto *PseudoSrcExpr = buildDeclRefExpr(
6983  *this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc());
6984  auto *DstVD =
6985  buildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst",
6986  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
6987  auto *PseudoDstExpr =
6988  buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
6989  // For arrays generate assignment operation for single element and replace
6990  // it by the original array element in CodeGen.
6991  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
6992  PseudoDstExpr, PseudoSrcExpr);
6993  if (AssignmentOp.isInvalid())
6994  continue;
6995  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
6996  /*DiscardedValue=*/true);
6997  if (AssignmentOp.isInvalid())
6998  continue;
6999 
7000  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
7001  // A list item may appear in a firstprivate or lastprivate clause but not
7002  // both.
7003  if (CurrDir == OMPD_distribute) {
7004  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
7005  if (DVar.CKind == OMPC_firstprivate) {
7006  Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
7007  ReportOriginalDSA(*this, DSAStack, VD, DVar);
7008  continue;
7009  }
7010  }
7011 
7012  if (TopDVar.CKind != OMPC_firstprivate)
7013  DSAStack->addDSA(VD, DE, OMPC_lastprivate);
7014  Vars.push_back(DE);
7015  SrcExprs.push_back(PseudoSrcExpr);
7016  DstExprs.push_back(PseudoDstExpr);
7017  AssignmentOps.push_back(AssignmentOp.get());
7018  }
7019 
7020  if (Vars.empty())
7021  return nullptr;
7022 
7023  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
7024  Vars, SrcExprs, DstExprs, AssignmentOps);
7025 }
7026 
7028  SourceLocation StartLoc,
7029  SourceLocation LParenLoc,
7030  SourceLocation EndLoc) {
7032  for (auto &RefExpr : VarList) {
7033  assert(RefExpr && "NULL expr in OpenMP shared clause.");
7034  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7035  // It will be analyzed later.
7036  Vars.push_back(RefExpr);
7037  continue;
7038  }
7039 
7040  SourceLocation ELoc = RefExpr->getExprLoc();
7041  // OpenMP [2.1, C/C++]
7042  // A list item is a variable name.
7043  // OpenMP [2.14.3.2, Restrictions, p.1]
7044  // A variable that is part of another variable (as an array or structure
7045  // element) cannot appear in a shared unless it is a static data member
7046  // of a C++ class.
7047  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
7048  if (!DE || !isa<VarDecl>(DE->getDecl())) {
7049  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7050  continue;
7051  }
7052  Decl *D = DE->getDecl();
7053  VarDecl *VD = cast<VarDecl>(D);
7054 
7055  QualType Type = VD->getType();
7056  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
7057  // It will be analyzed later.
7058  Vars.push_back(DE);
7059  continue;
7060  }
7061 
7062  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
7063  // in a Construct]
7064  // Variables with the predetermined data-sharing attributes may not be
7065  // listed in data-sharing attributes clauses, except for the cases
7066  // listed below. For these exceptions only, listing a predetermined
7067  // variable in a data-sharing attribute clause is allowed and overrides
7068  // the variable's predetermined data-sharing attributes.
7069  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
7070  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
7071  DVar.RefExpr) {
7072  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
7073  << getOpenMPClauseName(OMPC_shared);
7074  ReportOriginalDSA(*this, DSAStack, VD, DVar);
7075  continue;
7076  }
7077 
7078  DSAStack->addDSA(VD, DE, OMPC_shared);
7079  Vars.push_back(DE);
7080  }
7081 
7082  if (Vars.empty())
7083  return nullptr;
7084 
7085  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
7086 }
7087 
7088 namespace {
7089 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
7090  DSAStackTy *Stack;
7091 
7092 public:
7093  bool VisitDeclRefExpr(DeclRefExpr *E) {
7094  if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
7095  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false);
7096  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
7097  return false;
7098  if (DVar.CKind != OMPC_unknown)
7099  return true;
7100  DSAStackTy::DSAVarData DVarPrivate =
7101  Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false);
7102  if (DVarPrivate.CKind != OMPC_unknown)
7103  return true;
7104  return false;
7105  }
7106  return false;
7107  }
7108  bool VisitStmt(Stmt *S) {
7109  for (auto Child : S->children()) {
7110  if (Child && Visit(Child))
7111  return true;
7112  }
7113  return false;
7114  }
7115  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
7116 };
7117 } // namespace
7118 
7120  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
7122  CXXScopeSpec &ReductionIdScopeSpec,
7123  const DeclarationNameInfo &ReductionId) {
7124  // TODO: Allow scope specification search when 'declare reduction' is
7125  // supported.
7126  assert(ReductionIdScopeSpec.isEmpty() &&
7127  "No support for scoped reduction identifiers yet.");
7128 
7129  auto DN = ReductionId.getName();
7130  auto OOK = DN.getCXXOverloadedOperator();
7132 
7133  // OpenMP [2.14.3.6, reduction clause]
7134  // C
7135  // reduction-identifier is either an identifier or one of the following
7136  // operators: +, -, *, &, |, ^, && and ||
7137  // C++
7138  // reduction-identifier is either an id-expression or one of the following
7139  // operators: +, -, *, &, |, ^, && and ||
7140  // FIXME: Only 'min' and 'max' identifiers are supported for now.
7141  switch (OOK) {
7142  case OO_Plus:
7143  case OO_Minus:
7144  BOK = BO_Add;
7145  break;
7146  case OO_Star:
7147  BOK = BO_Mul;
7148  break;
7149  case OO_Amp:
7150  BOK = BO_And;
7151  break;
7152  case OO_Pipe:
7153  BOK = BO_Or;
7154  break;
7155  case OO_Caret:
7156  BOK = BO_Xor;
7157  break;
7158  case OO_AmpAmp:
7159  BOK = BO_LAnd;
7160  break;
7161  case OO_PipePipe:
7162  BOK = BO_LOr;
7163  break;
7164  case OO_New:
7165  case OO_Delete:
7166  case OO_Array_New:
7167  case OO_Array_Delete:
7168  case OO_Slash:
7169  case OO_Percent:
7170  case OO_Tilde:
7171  case OO_Exclaim:
7172  case OO_Equal:
7173  case OO_Less:
7174  case OO_Greater:
7175  case OO_LessEqual:
7176  case OO_GreaterEqual:
7177  case OO_PlusEqual:
7178  case OO_MinusEqual:
7179  case OO_StarEqual:
7180  case OO_SlashEqual:
7181  case OO_PercentEqual:
7182  case OO_CaretEqual:
7183  case OO_AmpEqual:
7184  case OO_PipeEqual:
7185  case OO_LessLess:
7186  case OO_GreaterGreater:
7187  case OO_LessLessEqual:
7188  case OO_GreaterGreaterEqual:
7189  case OO_EqualEqual:
7190  case OO_ExclaimEqual:
7191  case OO_PlusPlus:
7192  case OO_MinusMinus:
7193  case OO_Comma:
7194  case OO_ArrowStar:
7195  case OO_Arrow:
7196  case OO_Call:
7197  case OO_Subscript:
7198  case OO_Conditional:
7199  case OO_Coawait:
7201  llvm_unreachable("Unexpected reduction identifier");
7202  case OO_None:
7203  if (auto II = DN.getAsIdentifierInfo()) {
7204  if (II->isStr("max"))
7205  BOK = BO_GT;
7206  else if (II->isStr("min"))
7207  BOK = BO_LT;
7208  }
7209  break;
7210  }
7211  SourceRange ReductionIdRange;
7212  if (ReductionIdScopeSpec.isValid()) {
7213  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
7214  }
7215  ReductionIdRange.setEnd(ReductionId.getEndLoc());
7216  if (BOK == BO_Comma) {
7217  // Not allowed reduction identifier is found.
7218  Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier)
7219  << ReductionIdRange;
7220  return nullptr;
7221  }
7222 
7227  SmallVector<Expr *, 8> ReductionOps;
7228  for (auto RefExpr : VarList) {
7229  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
7230  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7231  // It will be analyzed later.
7232  Vars.push_back(RefExpr);
7233  Privates.push_back(nullptr);
7234  LHSs.push_back(nullptr);
7235  RHSs.push_back(nullptr);
7236  ReductionOps.push_back(nullptr);
7237  continue;
7238  }
7239 
7240  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
7241  RefExpr->isInstantiationDependent() ||
7242  RefExpr->containsUnexpandedParameterPack()) {
7243  // It will be analyzed later.
7244  Vars.push_back(RefExpr);
7245  Privates.push_back(nullptr);
7246  LHSs.push_back(nullptr);
7247  RHSs.push_back(nullptr);
7248  ReductionOps.push_back(nullptr);
7249  continue;
7250  }
7251 
7252  auto ELoc = RefExpr->getExprLoc();
7253  auto ERange = RefExpr->getSourceRange();
7254  // OpenMP [2.1, C/C++]
7255  // A list item is a variable or array section, subject to the restrictions
7256  // specified in Section 2.4 on page 42 and in each of the sections
7257  // describing clauses and directives for which a list appears.
7258  // OpenMP [2.14.3.3, Restrictions, p.1]
7259  // A variable that is part of another variable (as an array or
7260  // structure element) cannot appear in a private clause.
7261  auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
7262  auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr);
7263  auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr);
7264  if (!ASE && !OASE && (!DE || !isa<VarDecl>(DE->getDecl()))) {
7265  Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) << ERange;
7266  continue;
7267  }
7268  QualType Type;
7269  VarDecl *VD = nullptr;
7270  if (DE) {
7271  auto D = DE->getDecl();
7272  VD = cast<VarDecl>(D);
7273  Type = VD->getType();
7274  } else if (ASE) {
7275  Type = ASE->getType();
7276  auto *Base = ASE->getBase()->IgnoreParenImpCasts();
7277  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
7278  Base = TempASE->getBase()->IgnoreParenImpCasts();
7279  DE = dyn_cast<DeclRefExpr>(Base);
7280  if (DE)
7281  VD = dyn_cast<VarDecl>(DE->getDecl());
7282  if (!VD) {
7283  Diag(Base->getExprLoc(), diag::err_omp_expected_base_var_name)
7284  << 0 << Base->getSourceRange();
7285  continue;
7286  }
7287  } else if (OASE) {
7288  auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
7289  if (auto *ATy = BaseType->getAsArrayTypeUnsafe())
7290  Type = ATy->getElementType();
7291  else
7292  Type = BaseType->getPointeeType();
7293  auto *Base = OASE->getBase()->IgnoreParenImpCasts();
7294  while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
7295  Base = TempOASE->getBase()->IgnoreParenImpCasts();
7296  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
7297  Base = TempASE->getBase()->IgnoreParenImpCasts();
7298  DE = dyn_cast<DeclRefExpr>(Base);
7299  if (DE)
7300  VD = dyn_cast<VarDecl>(DE->getDecl());
7301  if (!VD) {
7302  Diag(Base->getExprLoc(), diag::err_omp_expected_base_var_name)
7303  << 1 << Base->getSourceRange();
7304  continue;
7305  }
7306  }
7307 
7308  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
7309  // A variable that appears in a private clause must not have an incomplete
7310  // type or a reference type.
7311  if (RequireCompleteType(ELoc, Type,
7312  diag::err_omp_reduction_incomplete_type))
7313  continue;
7314  // OpenMP [2.14.3.6, reduction clause, Restrictions]
7315  // Arrays may not appear in a reduction clause.
7316  if (Type.getNonReferenceType()->isArrayType()) {
7317  Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange;
7318  if (!ASE && !OASE) {
7319  bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7321  Diag(VD->getLocation(),
7322  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7323  << VD;
7324  }
7325  continue;
7326  }
7327  // OpenMP [2.14.3.6, reduction clause, Restrictions]
7328  // A list item that appears in a reduction clause must not be
7329  // const-qualified.
7330  if (Type.getNonReferenceType().isConstant(Context)) {
7331  Diag(ELoc, diag::err_omp_const_reduction_list_item)
7332  << getOpenMPClauseName(OMPC_reduction) << Type << ERange;
7333  if (!ASE && !OASE) {
7334  bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7336  Diag(VD->getLocation(),
7337  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7338  << VD;
7339  }
7340  continue;
7341  }
7342  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
7343  // If a list-item is a reference type then it must bind to the same object
7344  // for all threads of the team.
7345  if (!ASE && !OASE) {
7346  VarDecl *VDDef = VD->getDefinition();
7347  if (Type->isReferenceType() && VDDef) {
7348  DSARefChecker Check(DSAStack);
7349  if (Check.Visit(VDDef->getInit())) {
7350  Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
7351  Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
7352  continue;
7353  }
7354  }
7355  }
7356  // OpenMP [2.14.3.6, reduction clause, Restrictions]
7357  // The type of a list item that appears in a reduction clause must be valid
7358  // for the reduction-identifier. For a max or min reduction in C, the type
7359  // of the list item must be an allowed arithmetic data type: char, int,
7360  // float, double, or _Bool, possibly modified with long, short, signed, or
7361  // unsigned. For a max or min reduction in C++, the type of the list item
7362  // must be an allowed arithmetic data type: char, wchar_t, int, float,
7363  // double, or bool, possibly modified with long, short, signed, or unsigned.
7364  if ((BOK == BO_GT || BOK == BO_LT) &&
7365  !(Type->isScalarType() ||
7366  (getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
7367  Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
7368  << getLangOpts().CPlusPlus;
7369  if (!ASE && !OASE) {
7370  bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7372  Diag(VD->getLocation(),
7373  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7374  << VD;
7375  }
7376  continue;
7377  }
7378  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
7379  !getLangOpts().CPlusPlus && Type->isFloatingType()) {
7380  Diag(ELoc, diag::err_omp_clause_floating_type_arg);
7381  if (!ASE && !OASE) {
7382  bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7384  Diag(VD->getLocation(),
7385  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7386  << VD;
7387  }
7388  continue;
7389  }
7390  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
7391  // in a Construct]
7392  // Variables with the predetermined data-sharing attributes may not be
7393  // listed in data-sharing attributes clauses, except for the cases
7394  // listed below. For these exceptions only, listing a predetermined
7395  // variable in a data-sharing attribute clause is allowed and overrides
7396  // the variable's predetermined data-sharing attributes.
7397  // OpenMP [2.14.3.6, Restrictions, p.3]
7398  // Any number of reduction clauses can be specified on the directive,
7399  // but a list item can appear only once in the reduction clauses for that
7400  // directive.
7401  DSAStackTy::DSAVarData DVar;
7402  DVar = DSAStack->getTopDSA(VD, false);
7403  if (DVar.CKind == OMPC_reduction) {
7404  Diag(ELoc, diag::err_omp_once_referenced)
7405  << getOpenMPClauseName(OMPC_reduction);
7406  if (DVar.RefExpr) {
7407  Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
7408  }
7409  } else if (DVar.CKind != OMPC_unknown) {
7410  Diag(ELoc, diag::err_omp_wrong_dsa)
7411  << getOpenMPClauseName(DVar.CKind)
7412  << getOpenMPClauseName(OMPC_reduction);
7413  ReportOriginalDSA(*this, DSAStack, VD, DVar);
7414  continue;
7415  }
7416 
7417  // OpenMP [2.14.3.6, Restrictions, p.1]
7418  // A list item that appears in a reduction clause of a worksharing
7419  // construct must be shared in the parallel regions to which any of the
7420  // worksharing regions arising from the worksharing construct bind.
7421  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
7422  if (isOpenMPWorksharingDirective(CurrDir) &&
7423  !isOpenMPParallelDirective(CurrDir)) {
7424  DVar = DSAStack->getImplicitDSA(VD, true);
7425  if (DVar.CKind != OMPC_shared) {
7426  Diag(ELoc, diag::err_omp_required_access)
7427  << getOpenMPClauseName(OMPC_reduction)
7428  << getOpenMPClauseName(OMPC_shared);
7429  ReportOriginalDSA(*this, DSAStack, VD, DVar);
7430  continue;
7431  }
7432  }
7433 
7435  auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs",
7436  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7437  auto *RHSVD = buildVarDecl(*this, ELoc, Type, VD->getName(),
7438  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7439  auto PrivateTy = Type;
7440  if (OASE) {
7441  // For array sections only:
7442  // Create pseudo array type for private copy. The size for this array will
7443  // be generated during codegen.
7444  // For array subscripts or single variables Private Ty is the same as Type
7445  // (type of the variable or single array element).
7446  PrivateTy = Context.getVariableArrayType(
7447  Type, new (Context) OpaqueValueExpr(SourceLocation(),
7449  ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
7450  }
7451  // Private copy.
7452  auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, VD->getName(),
7453  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7454  // Add initializer for private variable.
7455  Expr *Init = nullptr;
7456  switch (BOK) {
7457  case BO_Add:
7458  case BO_Xor:
7459  case BO_Or:
7460  case BO_LOr:
7461  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
7462  if (Type->isScalarType() || Type->isAnyComplexType()) {
7463  Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get();
7464  }
7465  break;
7466  case BO_Mul:
7467  case BO_LAnd:
7468  if (Type->isScalarType() || Type->isAnyComplexType()) {
7469  // '*' and '&&' reduction ops - initializer is '1'.
7470  Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get();
7471  }
7472  break;
7473  case BO_And: {
7474  // '&' reduction op - initializer is '~0'.
7475  QualType OrigType = Type;
7476  if (auto *ComplexTy = OrigType->getAs<ComplexType>()) {
7477  Type = ComplexTy->getElementType();
7478  }
7479  if (Type->isRealFloatingType()) {
7480  llvm::APFloat InitValue =
7481  llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
7482  /*isIEEE=*/true);
7483  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
7484  Type, ELoc);
7485  } else if (Type->isScalarType()) {
7486  auto Size = Context.getTypeSize(Type);
7487  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
7488  llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
7489  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
7490  }
7491  if (Init && OrigType->isAnyComplexType()) {
7492  // Init = 0xFFFF + 0xFFFFi;
7493  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
7494  Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
7495  }
7496  Type = OrigType;
7497  break;
7498  }
7499  case BO_LT:
7500  case BO_GT: {
7501  // 'min' reduction op - initializer is 'Largest representable number in
7502  // the reduction list item type'.
7503  // 'max' reduction op - initializer is 'Least representable number in
7504  // the reduction list item type'.
7505  if (Type->isIntegerType() || Type->isPointerType()) {
7506  bool IsSigned = Type->hasSignedIntegerRepresentation();
7507  auto Size = Context.getTypeSize(Type);
7508  QualType IntTy =
7509  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
7510  llvm::APInt InitValue =
7511  (BOK != BO_LT)
7512  ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
7513  : llvm::APInt::getMinValue(Size)
7514  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
7515  : llvm::APInt::getMaxValue(Size);
7516  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
7517  if (Type->isPointerType()) {
7518  // Cast to pointer type.
7521  SourceLocation(), Init);
7522  if (CastExpr.isInvalid())
7523  continue;
7524  Init = CastExpr.get();
7525  }
7526  } else if (Type->isRealFloatingType()) {
7527  llvm::APFloat InitValue = llvm::APFloat::getLargest(
7528  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
7529  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
7530  Type, ELoc);
7531  }
7532  break;
7533  }
7534  case BO_PtrMemD:
7535  case BO_PtrMemI:
7536  case BO_MulAssign:
7537  case BO_Div:
7538  case BO_Rem:
7539  case BO_Sub:
7540  case BO_Shl:
7541  case BO_Shr:
7542  case BO_LE:
7543  case BO_GE:
7544  case BO_EQ:
7545  case BO_NE:
7546  case BO_AndAssign:
7547  case BO_XorAssign:
7548  case BO_OrAssign:
7549  case BO_Assign:
7550  case BO_AddAssign:
7551  case BO_SubAssign:
7552  case BO_DivAssign:
7553  case BO_RemAssign:
7554  case BO_ShlAssign:
7555  case BO_ShrAssign:
7556  case BO_Comma:
7557  llvm_unreachable("Unexpected reduction operation");
7558  }
7559  if (Init) {
7560  AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false,
7561  /*TypeMayContainAuto=*/false);
7562  } else
7563  ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false);
7564  if (!RHSVD->hasInit()) {
7565  Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
7566  << ReductionIdRange;
7567  if (VD) {
7568  bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
7570  Diag(VD->getLocation(),
7571  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7572  << VD;
7573  }
7574  continue;
7575  }
7576  // Store initializer for single element in private copy. Will be used during
7577  // codegen.
7578  PrivateVD->setInit(RHSVD->getInit());
7579  PrivateVD->setInitStyle(RHSVD->getInitStyle());
7580  auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc);
7581  auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc);
7582  auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc);
7583  ExprResult ReductionOp =
7584  BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK,
7585  LHSDRE, RHSDRE);
7586  if (ReductionOp.isUsable()) {
7587  if (BOK != BO_LT && BOK != BO_GT) {
7588  ReductionOp =
7589  BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
7590  BO_Assign, LHSDRE, ReductionOp.get());
7591  } else {
7592  auto *ConditionalOp = new (Context) ConditionalOperator(
7593  ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(),
7594  RHSDRE, Type, VK_LValue, OK_Ordinary);
7595  ReductionOp =
7596  BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
7597  BO_Assign, LHSDRE, ConditionalOp);
7598  }
7599  ReductionOp = ActOnFinishFullExpr(ReductionOp.get());
7600  }
7601  if (ReductionOp.isInvalid())
7602  continue;
7603 
7604  DSAStack->addDSA(VD, DE, OMPC_reduction);
7605  Vars.push_back(RefExpr);
7606  Privates.push_back(PrivateDRE);
7607  LHSs.push_back(LHSDRE);
7608  RHSs.push_back(RHSDRE);
7609  ReductionOps.push_back(ReductionOp.get());
7610  }
7611 
7612  if (Vars.empty())
7613  return nullptr;
7614 
7616  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
7617  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates,
7618  LHSs, RHSs, ReductionOps);
7619 }
7620 
7622  ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
7623  SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
7628  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
7629  LinKind == OMPC_LINEAR_unknown) {
7630  Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
7631  LinKind = OMPC_LINEAR_val;
7632  }
7633  for (auto &RefExpr : VarList) {
7634  assert(RefExpr && "NULL expr in OpenMP linear clause.");
7635  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7636  // It will be analyzed later.
7637  Vars.push_back(RefExpr);
7638  Privates.push_back(nullptr);
7639  Inits.push_back(nullptr);
7640  continue;
7641  }
7642 
7643  // OpenMP [2.14.3.7, linear clause]
7644  // A list item that appears in a linear clause is subject to the private
7645  // clause semantics described in Section 2.14.3.3 on page 159 except as
7646  // noted. In addition, the value of the new list item on each iteration
7647  // of the associated loop(s) corresponds to the value of the original
7648  // list item before entering the construct plus the logical number of
7649  // the iteration times linear-step.
7650 
7651  SourceLocation ELoc = RefExpr->getExprLoc();
7652  // OpenMP [2.1, C/C++]
7653  // A list item is a variable name.
7654  // OpenMP [2.14.3.3, Restrictions, p.1]
7655  // A variable that is part of another variable (as an array or
7656  // structure element) cannot appear in a private clause.
7657  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
7658  if (!DE || !isa<VarDecl>(DE->getDecl())) {
7659  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7660  continue;
7661  }
7662 
7663  VarDecl *VD = cast<VarDecl>(DE->getDecl());
7664 
7665  // OpenMP [2.14.3.7, linear clause]
7666  // A list-item cannot appear in more than one linear clause.
7667  // A list-item that appears in a linear clause cannot appear in any
7668  // other data-sharing attribute clause.
7669  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
7670  if (DVar.RefExpr) {
7671  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
7672  << getOpenMPClauseName(OMPC_linear);
7673  ReportOriginalDSA(*this, DSAStack, VD, DVar);
7674  continue;
7675  }
7676 
7677  QualType QType = VD->getType();
7678  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
7679  // It will be analyzed later.
7680  Vars.push_back(DE);
7681  Privates.push_back(nullptr);
7682  Inits.push_back(nullptr);
7683  continue;
7684  }
7685 
7686  // A variable must not have an incomplete type or a reference type.
7687  if (RequireCompleteType(ELoc, QType,
7688  diag::err_omp_linear_incomplete_type)) {
7689  continue;
7690  }
7691  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
7692  !QType->isReferenceType()) {
7693  Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
7694  << QType << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
7695  continue;
7696  }
7697  QType = QType.getNonReferenceType();
7698 
7699  // A list item must not be const-qualified.
7700  if (QType.isConstant(Context)) {
7701  Diag(ELoc, diag::err_omp_const_variable)
7702  << getOpenMPClauseName(OMPC_linear);
7703  bool IsDecl =
7705  Diag(VD->getLocation(),
7706  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7707  << VD;
7708  continue;
7709  }
7710 
7711  // A list item must be of integral or pointer type.
7712  QType = QType.getUnqualifiedType().getCanonicalType();
7713  const Type *Ty = QType.getTypePtrOrNull();
7714  if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
7715  !Ty->isPointerType())) {
7716  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType;
7717  bool IsDecl =
7719  Diag(VD->getLocation(),
7720  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7721  << VD;
7722  continue;
7723  }
7724 
7725  // Build private copy of original var.
7726  auto *Private = buildVarDecl(*this, ELoc, QType, VD->getName(),
7727  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7728  auto *PrivateRef = buildDeclRefExpr(
7729  *this, Private, DE->getType().getUnqualifiedType(), DE->getExprLoc());
7730  // Build var to save initial value.
7731  VarDecl *Init = buildVarDecl(*this, ELoc, QType, ".linear.start");
7732  Expr *InitExpr;
7733  if (LinKind == OMPC_LINEAR_uval)
7734  InitExpr = VD->getInit();
7735  else
7736  InitExpr = DE;
7737  AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
7738  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
7739  auto InitRef = buildDeclRefExpr(
7740  *this, Init, DE->getType().getUnqualifiedType(), DE->getExprLoc());
7741  DSAStack->addDSA(VD, DE, OMPC_linear);
7742  Vars.push_back(DE);
7743  Privates.push_back(PrivateRef);
7744  Inits.push_back(InitRef);
7745  }
7746 
7747  if (Vars.empty())
7748  return nullptr;
7749 
7750  Expr *StepExpr = Step;
7751  Expr *CalcStepExpr = nullptr;
7752  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
7753  !Step->isInstantiationDependent() &&
7755  SourceLocation StepLoc = Step->getLocStart();
7757  if (Val.isInvalid())
7758  return nullptr;
7759  StepExpr = Val.get();
7760 
7761  // Build var to save the step value.
7762  VarDecl *SaveVar =
7763  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
7764  ExprResult SaveRef =
7765  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
7767  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
7768  CalcStep = ActOnFinishFullExpr(CalcStep.get());
7769 
7770  // Warn about zero linear step (it would be probably better specified as
7771  // making corresponding variables 'const').
7772  llvm::APSInt Result;
7773  bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
7774  if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
7775  Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
7776  << (Vars.size() > 1);
7777  if (!IsConstant && CalcStep.isUsable()) {
7778  // Calculate the step beforehand instead of doing this on each iteration.
7779  // (This is not used if the number of iterations may be kfold-ed).
7780  CalcStepExpr = CalcStep.get();
7781  }
7782  }
7783 
7784  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
7785  ColonLoc, EndLoc, Vars, Privates, Inits,
7786  StepExpr, CalcStepExpr);
7787 }
7788 
7790  Expr *NumIterations, Sema &SemaRef,
7791  Scope *S) {
7792  // Walk the vars and build update/final expressions for the CodeGen.
7795  Expr *Step = Clause.getStep();
7796  Expr *CalcStep = Clause.getCalcStep();
7797  // OpenMP [2.14.3.7, linear clause]
7798  // If linear-step is not specified it is assumed to be 1.
7799  if (Step == nullptr)
7800  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
7801  else if (CalcStep)
7802  Step = cast<BinaryOperator>(CalcStep)->getLHS();
7803  bool HasErrors = false;
7804  auto CurInit = Clause.inits().begin();
7805  auto CurPrivate = Clause.privates().begin();
7806  auto LinKind = Clause.getModifier();
7807  for (auto &RefExpr : Clause.varlists()) {
7808  Expr *InitExpr = *CurInit;
7809 
7810  // Build privatized reference to the current linear var.
7811  auto DE = cast<DeclRefExpr>(RefExpr);
7812  Expr *CapturedRef;
7813  if (LinKind == OMPC_LINEAR_uval)
7814  CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
7815  else
7816  CapturedRef =
7817  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
7818  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
7819  /*RefersToCapture=*/true);
7820 
7821  // Build update: Var = InitExpr + IV * Step
7822  ExprResult Update =
7823  BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
7824  InitExpr, IV, Step, /* Subtract */ false);
7825  Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
7826  /*DiscardedValue=*/true);
7827 
7828  // Build final: Var = InitExpr + NumIterations * Step
7829  ExprResult Final =
7830  BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
7831  InitExpr, NumIterations, Step, /* Subtract */ false);
7832  Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
7833  /*DiscardedValue=*/true);
7834  if (!Update.isUsable() || !Final.isUsable()) {
7835  Updates.push_back(nullptr);
7836  Finals.push_back(nullptr);
7837  HasErrors = true;
7838  } else {
7839  Updates.push_back(Update.get());
7840  Finals.push_back(Final.get());
7841  }
7842  ++CurInit, ++CurPrivate;
7843  }
7844  Clause.setUpdates(Updates);
7845  Clause.setFinals(Finals);
7846  return HasErrors;
7847 }
7848 
7850  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
7852 
7854  for (auto &RefExpr : VarList) {
7855  assert(RefExpr && "NULL expr in OpenMP aligned clause.");
7856  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7857  // It will be analyzed later.
7858  Vars.push_back(RefExpr);
7859  continue;
7860  }
7861 
7862  SourceLocation ELoc = RefExpr->getExprLoc();
7863  // OpenMP [2.1, C/C++]
7864  // A list item is a variable name.
7865  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
7866  if (!DE || !isa<VarDecl>(DE->getDecl())) {
7867  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7868  continue;
7869  }
7870 
7871  VarDecl *VD = cast<VarDecl>(DE->getDecl());
7872 
7873  // OpenMP [2.8.1, simd construct, Restrictions]
7874  // The type of list items appearing in the aligned clause must be
7875  // array, pointer, reference to array, or reference to pointer.
7876  QualType QType = VD->getType();
7878  const Type *Ty = QType.getTypePtrOrNull();
7879  if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() &&
7880  !Ty->isPointerType())) {
7881  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
7882  << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange();
7883  bool IsDecl =
7885  Diag(VD->getLocation(),
7886  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7887  << VD;
7888  continue;
7889  }
7890 
7891  // OpenMP [2.8.1, simd construct, Restrictions]
7892  // A list-item cannot appear in more than one aligned clause.
7893  if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) {
7894  Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
7895  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
7896  << getOpenMPClauseName(OMPC_aligned);
7897  continue;
7898  }
7899 
7900  Vars.push_back(DE);
7901  }
7902 
7903  // OpenMP [2.8.1, simd construct, Description]
7904  // The parameter of the aligned clause, alignment, must be a constant
7905  // positive integer expression.
7906  // If no optional parameter is specified, implementation-defined default
7907  // alignments for SIMD instructions on the target platforms are assumed.
7908  if (Alignment != nullptr) {
7909  ExprResult AlignResult =
7910  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
7911  if (AlignResult.isInvalid())
7912  return nullptr;
7913  Alignment = AlignResult.get();
7914  }
7915  if (Vars.empty())
7916  return nullptr;
7917 
7918  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
7919  EndLoc, Vars, Alignment);
7920 }
7921 
7923  SourceLocation StartLoc,
7924  SourceLocation LParenLoc,
7925  SourceLocation EndLoc) {
7927  SmallVector<Expr *, 8> SrcExprs;
7928  SmallVector<Expr *, 8> DstExprs;
7929  SmallVector<Expr *, 8> AssignmentOps;
7930  for (auto &RefExpr : VarList) {
7931  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
7932  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7933  // It will be analyzed later.
7934  Vars.push_back(RefExpr);
7935  SrcExprs.push_back(nullptr);
7936  DstExprs.push_back(nullptr);
7937  AssignmentOps.push_back(nullptr);
7938  continue;
7939  }
7940 
7941  SourceLocation ELoc = RefExpr->getExprLoc();
7942  // OpenMP [2.1, C/C++]
7943  // A list item is a variable name.
7944  // OpenMP [2.14.4.1, Restrictions, p.1]
7945  // A list item that appears in a copyin clause must be threadprivate.
7946  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
7947  if (!DE || !isa<VarDecl>(DE->getDecl())) {
7948  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7949  continue;
7950  }
7951 
7952  Decl *D = DE->getDecl();
7953  VarDecl *VD = cast<VarDecl>(D);
7954 
7955  QualType Type = VD->getType();
7956  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
7957  // It will be analyzed later.
7958  Vars.push_back(DE);
7959  SrcExprs.push_back(nullptr);
7960  DstExprs.push_back(nullptr);
7961  AssignmentOps.push_back(nullptr);
7962  continue;
7963  }
7964 
7965  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
7966  // A list item that appears in a copyin clause must be threadprivate.
7967  if (!DSAStack->isThreadPrivate(VD)) {
7968  Diag(ELoc, diag::err_omp_required_access)
7969  << getOpenMPClauseName(OMPC_copyin)
7970  << getOpenMPDirectiveName(OMPD_threadprivate);
7971  continue;
7972  }
7973 
7974  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
7975  // A variable of class type (or array thereof) that appears in a
7976  // copyin clause requires an accessible, unambiguous copy assignment
7977  // operator for the class type.
7978  auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
7979  auto *SrcVD =
7980  buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(),
7981  ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7982  auto *PseudoSrcExpr = buildDeclRefExpr(
7983  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
7984  auto *DstVD =
7985  buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst",
7986  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
7987  auto *PseudoDstExpr =
7988  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
7989  // For arrays generate assignment operation for single element and replace
7990  // it by the original array element in CodeGen.
7991  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
7992  PseudoDstExpr, PseudoSrcExpr);
7993  if (AssignmentOp.isInvalid())
7994  continue;
7995  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
7996  /*DiscardedValue=*/true);
7997  if (AssignmentOp.isInvalid())
7998  continue;
7999 
8000  DSAStack->addDSA(VD, DE, OMPC_copyin);
8001  Vars.push_back(DE);
8002  SrcExprs.push_back(PseudoSrcExpr);
8003  DstExprs.push_back(PseudoDstExpr);
8004  AssignmentOps.push_back(AssignmentOp.get());
8005  }
8006 
8007  if (Vars.empty())
8008  return nullptr;
8009 
8010  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
8011  SrcExprs, DstExprs, AssignmentOps);
8012 }
8013 
8015  SourceLocation StartLoc,
8016  SourceLocation LParenLoc,
8017  SourceLocation EndLoc) {
8019  SmallVector<Expr *, 8> SrcExprs;
8020  SmallVector<Expr *, 8> DstExprs;
8021  SmallVector<Expr *, 8> AssignmentOps;
8022  for (auto &RefExpr : VarList) {
8023  assert(RefExpr && "NULL expr in OpenMP copyprivate clause.");
8024  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
8025  // It will be analyzed later.
8026  Vars.push_back(RefExpr);
8027  SrcExprs.push_back(nullptr);
8028  DstExprs.push_back(nullptr);
8029  AssignmentOps.push_back(nullptr);
8030  continue;
8031  }
8032 
8033  SourceLocation ELoc = RefExpr->getExprLoc();
8034  // OpenMP [2.1, C/C++]
8035  // A list item is a variable name.
8036  // OpenMP [2.14.4.1, Restrictions, p.1]
8037  // A list item that appears in a copyin clause must be threadprivate.
8038  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
8039  if (!DE || !isa<VarDecl>(DE->getDecl())) {
8040  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
8041  continue;
8042  }
8043 
8044  Decl *D = DE->getDecl();
8045  VarDecl *VD = cast<VarDecl>(D);
8046 
8047  QualType Type = VD->getType();
8048  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
8049  // It will be analyzed later.
8050  Vars.push_back(DE);
8051  SrcExprs.push_back(nullptr);
8052  DstExprs.push_back(nullptr);
8053  AssignmentOps.push_back(nullptr);
8054  continue;
8055  }
8056 
8057  // OpenMP [2.14.4.2, Restrictions, p.2]
8058  // A list item that appears in a copyprivate clause may not appear in a
8059  // private or firstprivate clause on the single construct.
8060  if (!DSAStack->isThreadPrivate(VD)) {
8061  auto DVar = DSAStack->getTopDSA(VD, false);
8062  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
8063  DVar.RefExpr) {
8064  Diag(ELoc, diag::err_omp_wrong_dsa)
8065  << getOpenMPClauseName(DVar.CKind)
8066  << getOpenMPClauseName(OMPC_copyprivate);
8067  ReportOriginalDSA(*this, DSAStack, VD, DVar);
8068  continue;
8069  }
8070 
8071  // OpenMP [2.11.4.2, Restrictions, p.1]
8072  // All list items that appear in a copyprivate clause must be either
8073  // threadprivate or private in the enclosing context.
8074  if (DVar.CKind == OMPC_unknown) {
8075  DVar = DSAStack->getImplicitDSA(VD, false);
8076  if (DVar.CKind == OMPC_shared) {
8077  Diag(ELoc, diag::err_omp_required_access)
8078  << getOpenMPClauseName(OMPC_copyprivate)
8079  << "threadprivate or private in the enclosing context";
8080  ReportOriginalDSA(*this, DSAStack, VD, DVar);
8081  continue;
8082  }
8083  }
8084  }
8085 
8086  // Variably modified types are not supported.
8087  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
8088  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
8089  << getOpenMPClauseName(OMPC_copyprivate) << Type
8090  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
8091  bool IsDecl =
8093  Diag(VD->getLocation(),
8094  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
8095  << VD;
8096  continue;
8097  }
8098 
8099  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
8100  // A variable of class type (or array thereof) that appears in a
8101  // copyin clause requires an accessible, unambiguous copy assignment
8102  // operator for the class type.
8103  Type = Context.getBaseElementType(Type.getNonReferenceType())
8104  .getUnqualifiedType();
8105  auto *SrcVD =
8106  buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src",
8107  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
8108  auto *PseudoSrcExpr =
8109  buildDeclRefExpr(*this, SrcVD, Type, DE->getExprLoc());
8110  auto *DstVD =
8111  buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst",
8112  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
8113  auto *PseudoDstExpr =
8114  buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
8115  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
8116  PseudoDstExpr, PseudoSrcExpr);
8117  if (AssignmentOp.isInvalid())
8118  continue;
8119  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
8120  /*DiscardedValue=*/true);
8121  if (AssignmentOp.isInvalid())
8122  continue;
8123 
8124  // No need to mark vars as copyprivate, they are already threadprivate or
8125  // implicitly private.
8126  Vars.push_back(DE);
8127  SrcExprs.push_back(PseudoSrcExpr);
8128  DstExprs.push_back(PseudoDstExpr);
8129  AssignmentOps.push_back(AssignmentOp.get());
8130  }
8131 
8132  if (Vars.empty())
8133  return nullptr;
8134 
8135  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
8136  Vars, SrcExprs, DstExprs, AssignmentOps);
8137 }
8138 
8140  SourceLocation StartLoc,
8141  SourceLocation LParenLoc,
8142  SourceLocation EndLoc) {
8143  if (VarList.empty())
8144  return nullptr;
8145 
8146  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
8147 }
8148 
8149 OMPClause *
8152  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
8153  SourceLocation LParenLoc, SourceLocation EndLoc) {
8154  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
8155  DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
8156  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
8157  << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
8158  return nullptr;
8159  }
8160  if (DSAStack->getCurrentDirective() != OMPD_ordered &&
8161  (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
8162  DepKind == OMPC_DEPEND_sink)) {
8163  unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
8164  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
8165  << getListOfPossibleValues(OMPC_depend, /*First=*/0,
8166  /*Last=*/OMPC_DEPEND_unknown, Except)
8167  << getOpenMPClauseName(OMPC_depend);
8168  return nullptr;
8169  }
8171  llvm::APSInt DepCounter(/*BitWidth=*/32);
8172  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
8173  if (DepKind == OMPC_DEPEND_sink) {
8174  if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) {
8175  TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
8176  TotalDepCount.setIsUnsigned(/*Val=*/true);
8177  }
8178  }
8179  if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
8180  DSAStack->getParentOrderedRegionParam()) {
8181  for (auto &RefExpr : VarList) {
8182  assert(RefExpr && "NULL expr in OpenMP shared clause.");
8183  if (isa<DependentScopeDeclRefExpr>(RefExpr) ||
8184  (DepKind == OMPC_DEPEND_sink && CurContext->isDependentContext())) {
8185  // It will be analyzed later.
8186  Vars.push_back(RefExpr);
8187  continue;
8188  }
8189 
8190  SourceLocation ELoc = RefExpr->getExprLoc();
8191  auto *SimpleExpr = RefExpr->IgnoreParenCasts();
8192  if (DepKind == OMPC_DEPEND_sink) {
8193  if (DepCounter >= TotalDepCount) {
8194  Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
8195  continue;
8196  }
8197  ++DepCounter;
8198  // OpenMP [2.13.9, Summary]
8199  // depend(dependence-type : vec), where dependence-type is:
8200  // 'sink' and where vec is the iteration vector, which has the form:
8201  // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
8202  // where n is the value specified by the ordered clause in the loop
8203  // directive, xi denotes the loop iteration variable of the i-th nested
8204  // loop associated with the loop directive, and di is a constant
8205  // non-negative integer.
8206  SimpleExpr = SimpleExpr->IgnoreImplicit();
8207  auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
8208  if (!DE) {
8210  SourceLocation OOLoc;
8211  Expr *LHS, *RHS;
8212  if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
8213  OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
8214  OOLoc = BO->getOperatorLoc();
8215  LHS = BO->getLHS()->IgnoreParenImpCasts();
8216  RHS = BO->getRHS()->IgnoreParenImpCasts();
8217  } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
8218  OOK = OCE->getOperator();
8219  OOLoc = OCE->getOperatorLoc();
8220  LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
8221  RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
8222  } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
8223  OOK = MCE->getMethodDecl()
8224  ->getNameInfo()
8225  .getName()
8226  .getCXXOverloadedOperator();
8227  OOLoc = MCE->getCallee()->getExprLoc();
8228  LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
8229  RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
8230  } else {
8231  Diag(ELoc, diag::err_omp_depend_sink_wrong_expr);
8232  continue;
8233  }
8234  DE = dyn_cast<DeclRefExpr>(LHS);
8235  if (!DE) {
8236  Diag(LHS->getExprLoc(),
8237  diag::err_omp_depend_sink_expected_loop_iteration)
8238  << DSAStack->getParentLoopControlVariable(
8239  DepCounter.getZExtValue());
8240  continue;
8241  }
8242  if (OOK != OO_Plus && OOK != OO_Minus) {
8243  Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
8244  continue;
8245  }
8246  ExprResult Res = VerifyPositiveIntegerConstantInClause(
8247  RHS, OMPC_depend, /*StrictlyPositive=*/false);
8248  if (Res.isInvalid())
8249  continue;
8250  }
8251  auto *VD = dyn_cast<VarDecl>(DE->getDecl());
8252  if (!CurContext->isDependentContext() &&
8253  DSAStack->getParentOrderedRegionParam() &&
8254  (!VD || DepCounter != DSAStack->isParentLoopControlVariable(VD))) {
8255  Diag(DE->getExprLoc(),
8256  diag::err_omp_depend_sink_expected_loop_iteration)
8257  << DSAStack->getParentLoopControlVariable(
8258  DepCounter.getZExtValue());
8259  continue;
8260  }
8261  } else {
8262  // OpenMP [2.11.1.1, Restrictions, p.3]
8263  // A variable that is part of another variable (such as a field of a
8264  // structure) but is not an array element or an array section cannot
8265  // appear in a depend clause.
8266  auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
8267  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
8268  auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
8269  if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
8270  (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) ||
8271  (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
8272  !ASE->getBase()->getType()->isArrayType())) {
8273  Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
8274  << RefExpr->getSourceRange();
8275  continue;
8276  }
8277  }
8278 
8279  Vars.push_back(RefExpr->IgnoreParenImpCasts());
8280  }
8281 
8282  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
8283  TotalDepCount > VarList.size() &&
8284  DSAStack->getParentOrderedRegionParam()) {
8285  Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
8286  << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
8287  }
8288  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
8289  Vars.empty())
8290  return nullptr;
8291  }
8292 
8293  return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind,
8294  DepLoc, ColonLoc, Vars);
8295 }
8296 
8298  SourceLocation LParenLoc,
8299  SourceLocation EndLoc) {
8300  Expr *ValExpr = Device;
8301 
8302  // OpenMP [2.9.1, Restrictions]
8303  // The device expression must evaluate to a non-negative integer value.
8304  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
8305  /*StrictlyPositive=*/false))
8306  return nullptr;
8307 
8308  return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8309 }
8310 
8311 static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc,
8312  DSAStackTy *Stack, CXXRecordDecl *RD) {
8313  if (!RD || RD->isInvalidDecl())
8314  return true;
8315 
8316  if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
8317  if (auto *CTD = CTSD->getSpecializedTemplate())
8318  RD = CTD->getTemplatedDecl();
8319  auto QTy = SemaRef.Context.getRecordType(RD);
8320  if (RD->isDynamicClass()) {
8321  SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
8322  SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target);
8323  return false;
8324  }
8325  auto *DC = RD;
8326  bool IsCorrect = true;
8327  for (auto *I : DC->decls()) {
8328  if (I) {
8329  if (auto *MD = dyn_cast<CXXMethodDecl>(I)) {
8330  if (MD->isStatic()) {
8331  SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
8332  SemaRef.Diag(MD->getLocation(),
8333  diag::note_omp_static_member_in_target);
8334  IsCorrect = false;
8335  }
8336  } else if (auto *VD = dyn_cast<VarDecl>(I)) {
8337  if (VD->isStaticDataMember()) {
8338  SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
8339  SemaRef.Diag(VD->getLocation(),
8340  diag::note_omp_static_member_in_target);
8341  IsCorrect = false;
8342  }
8343  }
8344  }
8345  }
8346 
8347  for (auto &I : RD->bases()) {
8348  if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack,
8349  I.getType()->getAsCXXRecordDecl()))
8350  IsCorrect = false;
8351  }
8352  return IsCorrect;
8353 }
8354 
8355 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
8356  DSAStackTy *Stack, QualType QTy) {
8357  NamedDecl *ND;
8358  if (QTy->isIncompleteType(&ND)) {
8359  SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
8360  return false;
8361  } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) {
8362  if (!RD->isInvalidDecl() &&
8363  !IsCXXRecordForMappable(SemaRef, SL, Stack, RD))
8364  return false;
8365  }
8366  return true;
8367 }
8368 
8370  OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType,
8372  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
8374 
8375  for (auto &RE : VarList) {
8376  assert(RE && "Null expr in omp map");
8377  if (isa<DependentScopeDeclRefExpr>(RE)) {
8378  // It will be analyzed later.
8379  Vars.push_back(RE);
8380  continue;
8381  }
8382  SourceLocation ELoc = RE->getExprLoc();
8383 
8384  // OpenMP [2.14.5, Restrictions]
8385  // A variable that is part of another variable (such as field of a
8386  // structure) but is not an array element or an array section cannot appear
8387  // in a map clause.
8388  auto *VE = RE->IgnoreParenLValueCasts();
8389 
8390  if (VE->isValueDependent() || VE->isTypeDependent() ||
8391  VE->isInstantiationDependent() ||
8392  VE->containsUnexpandedParameterPack()) {
8393  // It will be analyzed later.
8394  Vars.push_back(RE);
8395  continue;
8396  }
8397 
8398  auto *SimpleExpr = RE->IgnoreParenCasts();
8399  auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
8400  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
8401  auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
8402 
8403  if (!RE->IgnoreParenImpCasts()->isLValue() ||
8404  (!OASE && !ASE && !DE) ||
8405  (DE && !isa<VarDecl>(DE->getDecl())) ||
8406  (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
8407  !ASE->getBase()->getType()->isArrayType())) {
8408  Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
8409  << RE->getSourceRange();
8410  continue;
8411  }
8412 
8413  Decl *D = nullptr;
8414  if (DE) {
8415  D = DE->getDecl();
8416  } else if (ASE) {
8417  auto *B = ASE->getBase()->IgnoreParenCasts();
8418  D = dyn_cast<DeclRefExpr>(B)->getDecl();
8419  } else if (OASE) {
8420  auto *B = OASE->getBase();
8421  D = dyn_cast<DeclRefExpr>(B)->getDecl();
8422  }
8423  assert(D && "Null decl on map clause.");
8424  auto *VD = cast<VarDecl>(D);
8425 
8426  // OpenMP [2.14.5, Restrictions, p.8]
8427  // threadprivate variables cannot appear in a map clause.
8428  if (DSAStack->isThreadPrivate(VD)) {
8429  auto DVar = DSAStack->getTopDSA(VD, false);
8430  Diag(ELoc, diag::err_omp_threadprivate_in_map);
8431  ReportOriginalDSA(*this, DSAStack, VD, DVar);
8432  continue;
8433  }
8434 
8435  // OpenMP [2.14.5, Restrictions, p.2]
8436  // At most one list item can be an array item derived from a given variable
8437  // in map clauses of the same construct.
8438  // OpenMP [2.14.5, Restrictions, p.3]
8439  // List items of map clauses in the same construct must not share original
8440  // storage.
8441  // OpenMP [2.14.5, Restrictions, C/C++, p.2]
8442  // A variable for which the type is pointer, reference to array, or
8443  // reference to pointer and an array section derived from that variable
8444  // must not appear as list items of map clauses of the same construct.
8445  DSAStackTy::MapInfo MI = DSAStack->IsMappedInCurrentRegion(VD);
8446  if (MI.RefExpr) {
8447  Diag(ELoc, diag::err_omp_map_shared_storage) << ELoc;
8448  Diag(MI.RefExpr->getExprLoc(), diag::note_used_here)
8449  << MI.RefExpr->getSourceRange();
8450  continue;
8451  }
8452 
8453  // OpenMP [2.14.5, Restrictions, C/C++, p.3,4]
8454  // A variable for which the type is pointer, reference to array, or
8455  // reference to pointer must not appear as a list item if the enclosing
8456  // device data environment already contains an array section derived from
8457  // that variable.
8458  // An array section derived from a variable for which the type is pointer,
8459  // reference to array, or reference to pointer must not appear as a list
8460  // item if the enclosing device data environment already contains that
8461  // variable.
8462  QualType Type = VD->getType();
8463  MI = DSAStack->getMapInfoForVar(VD);
8464  if (MI.RefExpr && (isa<DeclRefExpr>(MI.RefExpr->IgnoreParenLValueCasts()) !=
8465  isa<DeclRefExpr>(VE)) &&
8466  (Type->isPointerType() || Type->isReferenceType())) {
8467  Diag(ELoc, diag::err_omp_map_shared_storage) << ELoc;
8468  Diag(MI.RefExpr->getExprLoc(), diag::note_used_here)
8469  << MI.RefExpr->getSourceRange();
8470  continue;
8471  }
8472 
8473  // OpenMP [2.14.5, Restrictions, C/C++, p.7]
8474  // A list item must have a mappable type.
8475  if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), *this,
8476  DSAStack, Type))
8477  continue;
8478 
8479  Vars.push_back(RE);
8480  MI.RefExpr = RE;
8481  DSAStack->addMapInfoForVar(VD, MI);
8482  }
8483  if (Vars.empty())
8484  return nullptr;
8485 
8486  return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
8487  MapTypeModifier, MapType, MapLoc);
8488 }
8489 
8491  SourceLocation StartLoc,
8492  SourceLocation LParenLoc,
8493  SourceLocation EndLoc) {
8494  Expr *ValExpr = NumTeams;
8495 
8496  // OpenMP [teams Constrcut, Restrictions]
8497  // The num_teams expression must evaluate to a positive integer value.
8498  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
8499  /*StrictlyPositive=*/true))
8500  return nullptr;
8501 
8502  return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8503 }
8504 
8506  SourceLocation StartLoc,
8507  SourceLocation LParenLoc,
8508  SourceLocation EndLoc) {
8509  Expr *ValExpr = ThreadLimit;
8510 
8511  // OpenMP [teams Constrcut, Restrictions]
8512  // The thread_limit expression must evaluate to a positive integer value.
8513  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
8514  /*StrictlyPositive=*/true))
8515  return nullptr;
8516 
8517  return new (Context) OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc,
8518  EndLoc);
8519 }
8520 
8522  SourceLocation StartLoc,
8523  SourceLocation LParenLoc,
8524  SourceLocation EndLoc) {
8525  Expr *ValExpr = Priority;
8526 
8527  // OpenMP [2.9.1, task Constrcut]
8528  // The priority-value is a non-negative numerical scalar expression.
8529  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
8530  /*StrictlyPositive=*/false))
8531  return nullptr;
8532 
8533  return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8534 }
8535 
8537  SourceLocation StartLoc,
8538  SourceLocation LParenLoc,
8539  SourceLocation EndLoc) {
8540  Expr *ValExpr = Grainsize;
8541 
8542  // OpenMP [2.9.2, taskloop Constrcut]
8543  // The parameter of the grainsize clause must be a positive integer
8544  // expression.
8545  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
8546  /*StrictlyPositive=*/true))
8547  return nullptr;
8548 
8549  return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8550 }
8551 
8553  SourceLocation StartLoc,
8554  SourceLocation LParenLoc,
8555  SourceLocation EndLoc) {
8556  Expr *ValExpr = NumTasks;
8557 
8558  // OpenMP [2.9.2, taskloop Constrcut]
8559  // The parameter of the num_tasks clause must be a positive integer
8560  // expression.
8561  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
8562  /*StrictlyPositive=*/true))
8563  return nullptr;
8564 
8565  return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8566 }
8567 
8569  SourceLocation LParenLoc,
8570  SourceLocation EndLoc) {
8571  // OpenMP [2.13.2, critical construct, Description]
8572  // ... where hint-expression is an integer constant expression that evaluates
8573  // to a valid lock hint.
8574  ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
8575  if (HintExpr.isInvalid())
8576  return nullptr;
8577  return new (Context)
8578  OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
8579 }
8580 
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL)
Creates clause with a list of variables VL.
Expr * NLB
Update of LowerBound for statically sheduled 'omp for' loops.
Definition: StmtOpenMP.h:512
Defines the clang::ASTContext interface.
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false)
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
Definition: SemaExpr.cpp:13815
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Definition: StmtOpenMP.h:524
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
Definition: StmtOpenMP.h:522
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
void setImplicit(bool I=true)
Definition: DeclBase.h:515
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
Definition: OpenMPClause.h:794
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:169
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
CanQualType VoidPtrTy
Definition: ASTContext.h:895
A (possibly-)qualified type.
Definition: Type.h:575
Simple class containing the result of Sema::CorrectTypo.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Definition: Expr.h:211
base_class_range bases()
Definition: DeclCXX.h:713
bool isInvalid() const
Definition: Ownership.h:159
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:840
ArrayRef< OMPClause * > clauses()
Definition: StmtOpenMP.h:216
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition: Expr.h:3011
DeclContext * getCurLexicalContext() const
Definition: Sema.h:9208
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
Definition: SemaStmt.cpp:3814
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
Definition: SemaExpr.cpp:6798
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
Definition: SemaExpr.cpp:3114
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:187
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
Definition: SemaOpenMP.cpp:939
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc...
Definition: Sema.h:2636
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
Definition: Decl.h:164
Expr * getSimdlen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:436
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1757
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type...
Definition: Type.cpp:2627
const LangOptions & getLangOpts() const
Definition: Sema.h:1041
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
DeclClass * getAsSingle() const
Definition: Sema/Lookup.h:448
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement...
SourceLocation getEndLoc() const
getEndLoc - Retrieve the location of the last token.
static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start)
Build 'VarRef = Start.
static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition: Scope.h:215
ActionResult< Expr * > ExprResult
Definition: Ownership.h:252
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
The current expression is potentially evaluated at run time, which means that code may be generated t...
Definition: Sema.h:781
Expr * EUB
EnsureUpperBound – expression LB = min(LB, NumIterations).
Definition: StmtOpenMP.h:510
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc)
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition: Sema.h:1118
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:77
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Definition: AttrIterator.h:48
This represents 'grainsize' clause in the '#pragma omp ...' directive.
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel)
Creates directive.
Definition: StmtOpenMP.cpp:245
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
Definition: Decl.cpp:2002
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
This represents 'if' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:152
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
bool isEnumeralType() const
Definition: Type.h:5365
bool hasDefinition() const
Definition: DeclCXX.h:680
PtrTy get() const
Definition: Ownership.h:163
This represents 'priority' clause in the '#pragma omp ...' directive.
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate)
Creates directive with a list of Clauses and 'x', 'v' and 'expr' parts of the atomic construct (see S...
Definition: StmtOpenMP.cpp:640
The base class of the type hierarchy.
Definition: Type.h:1249
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:884
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:313
QualType getRecordType(const RecordDecl *Decl) const
const Expr * getInit() const
Definition: Decl.h:1070
A container of type source information.
Definition: Decl.h:61
This represents 'update' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
Definition: Ownership.h:45
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
SourceLocation getOperatorLoc() const
Definition: Expr.h:2915
static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2134
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
SourceLocation getTemplateKeywordLoc() const
Retrieve the location of the template keyword preceding this name, if any.
Definition: Expr.h:1060
void setNothrow(bool Nothrow=true)
Definition: Decl.cpp:4010
This represents 'read' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:997
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:699
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:25
bool isFileVarDecl() const
isFileVarDecl - Returns true for file scoped variable declaration.
Definition: Decl.h:1044
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:794
DiagnosticsEngine & Diags
Definition: Sema.h:297
This represents 'num_threads' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:289
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
TLSKind getTLSKind() const
Definition: Decl.cpp:1818
varlist_range varlists()
Definition: OpenMPClause.h:119
Extra information about a function prototype.
Definition: Type.h:3067
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:1793
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:926
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
Definition: Expr.h:716
void setBegin(SourceLocation b)
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:338
Not a TLS variable.
Definition: Decl.h:716
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
Expr * getNumForLoops() const
Return the number of associated for-loops.
Definition: OpenMPClause.h:887
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition: DeclCXX.h:1163
bool isEmpty() const
No scope specifier.
Definition: DeclSpec.h:189
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
Definition: ScopeInfo.h:599
This represents 'nogroup' clause in the '#pragma omp ...' directive.
void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto)
Definition: SemaDecl.cpp:9663
QualType withConst() const
Retrieves a version of this type with const applied.
This represents 'safelen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:347
Expr * LastIteration
Loop last iteration number.
Definition: StmtOpenMP.h:488
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
A semantic tree transformation that allows one to transform one abstract syntax tree into another...
Definition: TreeTransform.h:95
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
Definition: OpenMPKinds.cpp:61
DeclarationName getName() const
getName - Returns the embedded declaration name.
One of these records is kept for each identifier that is lexed.
bool isScalarType() const
Definition: Type.h:5581
CalcStep
Definition: OpenMPClause.h:311
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
bool isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level)
Check if the specified variable is captured by 'target' directive.
Definition: SemaOpenMP.cpp:914
bool isUnset() const
Definition: Ownership.h:161
Step
Definition: OpenMPClause.h:311
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4381
bool hasAttr() const
Definition: DeclBase.h:498
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL)
Creates clause with a list of variables VL.
A C++ nested-name-specifier augmented with source location information.
This represents 'simd' clause in the '#pragma omp ...' directive.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
Definition: OpenMPClause.h:789
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool isReferenceType() const
Definition: Type.h:5314
Scope * TheScope
This is the enclosing scope of the captured region.
Definition: ScopeInfo.h:603
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Definition: OpenMPKinds.h:83
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
SourceLocation getLocStart() const
Returns the starting location of the clause.
Definition: OpenMPClause.h:46
void Deallocate(void *Ptr) const
Definition: ASTContext.h:566
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
Definition: SemaOpenMP.cpp:924
bool isTranslationUnit() const
Definition: DeclBase.h:1269
bool isPreviousDeclInSameBlockScope() const
Whether this local extern variable declaration's previous declaration was declared in the same block ...
Definition: Decl.h:1217
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:1962
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr)
Definition: Expr.cpp:368
Defines some OpenMP-specific enums and functions.
bool isOpenMPPrivateVar(VarDecl *VD, unsigned Level)
Check if the specified variable is used in 'private' clause.
Definition: SemaOpenMP.cpp:908
void PopExpressionEvaluationContext()
Definition: SemaExpr.cpp:12479
This represents '#pragma omp critical' directive.
Definition: StmtOpenMP.h:1147
void EndOpenMPClause()
End analysis of clauses.
Definition: SemaOpenMP.cpp:935
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:875
static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:102
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:432
Expr * getLHS() const
Definition: Expr.h:2921
VerifyDiagnosticConsumer::Directive Directive
ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, Expr *SubExpr)
Definition: SemaExpr.cpp:14020
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target data' after parsing of the associated statement.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Definition: OpenMPClause.h:805
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
BinaryOperatorKind
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:568
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
Represents the results of name lookup.
Definition: Sema/Lookup.h:30
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:580
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
DeclarationNameInfo getNameInfo() const
Definition: Expr.h:1011
bool isFunctionOrMethodVarDecl() const
isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but excludes variables declared in blocks...
Definition: Decl.h:970
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
Definition: SemaOpenMP.cpp:574
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:135
StmtResult StmtError()
Definition: Ownership.h:268
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2875
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
Definition: Expr.h:146
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:3389
This represents 'default' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:509
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:38
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence...
Definition: SemaInit.cpp:6046
This represents 'final' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:235
This represents 'mergeable' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:966
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
Definition: OpenMPClause.h:810
Expr * CalcLastIteration
Calculation of last iteration.
Definition: StmtOpenMP.h:492
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:63
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:2610
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
Definition: Type.cpp:1886
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:908
Preprocessor & PP
Definition: Sema.h:294
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:1800
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Definition: Expr.cpp:720
An ordinary object is located at an address in memory.
Definition: Specifiers.h:118
static QualType getBaseOriginalType(Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:4013
detail::InMemoryDirectory::const_iterator I
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
QualType getType() const
Definition: Decl.h:530
bool isInvalid() const
const LangOptions & LangOpts
Definition: Sema.h:293
Expr * NUB
Update of UpperBound for statically sheduled 'omp for' loops.
Definition: StmtOpenMP.h:514
Expr * Cond
Loop condition.
Definition: StmtOpenMP.h:496
static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, DSAStackTy *Stack, CXXRecordDecl *RD)
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Expr * PreCond
Loop pre-condition.
Definition: StmtOpenMP.h:494
AnnotatingParser & P
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
Definition: OpenMPClause.h:56
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:83
OpenMP 4.0 [2.4, Array Sections].
Definition: ExprOpenMP.h:45
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
Definition: StmtOpenMP.h:484
SourceLocation getLocEnd() const
Returns the ending location of the clause.
Definition: OpenMPClause.h:48
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:3148
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:259
bool isNamespace() const
Definition: DeclBase.h:1277
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, bool TypeMayContainAuto)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Definition: SemaDecl.cpp:9194
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
This represents 'threads' clause in the '#pragma omp ...' directive.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc...
Definition: SemaExpr.cpp:10435
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
Retains information about a captured region.
Definition: ScopeInfo.h:596
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate', 'reduction' etc.
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL)
Definition: DeclOpenMP.cpp:28
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
std::vector< bool > & Stack
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Definition: Expr.h:188
Expr * IterationVarRef
Loop iteration variable.
Definition: StmtOpenMP.h:486
const SmallVectorImpl< AnnotatedLine * >::const_iterator End
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:415
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:1793
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:671
OMPClause * ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'map' clause.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
const Type * getTypePtrOrNull() const
Definition: Type.h:5093
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:581
This represents 'capture' clause in the '#pragma omp atomic' directive.
Expr - This represents one expression.
Definition: Expr.h:104
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
Definition: SemaOpenMP.cpp:931
static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract)
Build 'VarRef = Start + Iter * Step'.
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
Definition: Scope.h:306
bool isAnyComplexType() const
Definition: Type.h:5368
static OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:402
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
Definition: DeclBase.cpp:943
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
Inits[]
Definition: OpenMPClause.h:310
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:293
void setInit(Expr *I)
Definition: Decl.cpp:2087
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Sema/Lookup.h:458
Defines the clang::Preprocessor interface.
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, bool AllowFold=true)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
Definition: SemaExpr.cpp:12273
OpenMPClauseKind
OpenMP clauses.
Definition: OpenMPKinds.h:33
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
DeclContext * getDeclContext()
Definition: DeclBase.h:393
bool isFloatingType() const
Definition: Type.cpp:1777
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
Definition: Expr.cpp:746
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps)
Creates clause with a list of variables VL.
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:6518
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
Definition: StmtOpenMP.h:528
This represents 'ordered' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:852
void DiscardCleanupsInEvaluationContext()
Definition: SemaExpr.cpp:12537
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:614
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1751
bool isExceptionVariable() const
Determine whether this variable is the exception variable in a C++ catch statememt or an Objective-C ...
Definition: Decl.h:1140
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
OMPClause * ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
This represents 'collapse' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:457
ValueDecl * getDecl()
Definition: Expr.h:1007
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:697
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2392
The result type of a method or function.
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
Definition: OpenMPKinds.h:50
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name, with source-location information.
Definition: Expr.h:1026
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:747
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:602
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:1908
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
Definition: SemaOpenMP.cpp:40
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
Definition: Expr.h:1409
OMPClause * ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
Expr * NumIterations
Loop number of iterations.
Definition: StmtOpenMP.h:490
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
Definition: Sema.h:4784
static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
This represents 'untied' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:934
AttrVec & getAttrs()
Definition: DeclBase.h:443
bool isAmbiguous() const
Definition: Sema/Lookup.h:242
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:2463
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:3454
Expr * ST
Stride - local variable passed to runtime.
Definition: StmtOpenMP.h:508
void addAttr(Attr *A)
Definition: DeclBase.h:449
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
Definition: StmtOpenMP.h:518
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Definition: Expr.h:840
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause * > Clauses)
#define false
Definition: stdbool.h:33
Kind
This captures a statement into a function.
Definition: Stmt.h:1984
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Definition: StmtOpenMP.h:516
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents 'hint' clause in the '#pragma omp ...' directive.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
Definition: OpenMPKinds.h:75
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:33
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:721
bool isValid() const
Return true if this is a valid SourceLocation object.
OverloadedOperatorKind getCXXOverloadedOperator() const
getCXXOverloadedOperator - If this name is the name of an overloadable operator in C++ (e...
bool isConstant(ASTContext &Ctx) const
Definition: Type.h:712
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
Definition: DeclSpec.cpp:143
This represents 'schedule' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:653
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
ASTContext & getASTContext() const
Definition: Sema.h:1048
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
Definition: Expr.h:1127
bool isLocalVarDecl() const
isLocalVarDecl - Returns true for local variable declarations other than parameters.
Definition: Decl.h:955
void setReferenced(bool R=true)
Definition: DeclBase.h:543
OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:23
IdentifierTable & getIdentifierTable()
Definition: Preprocessor.h:690
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
QualType withConst() const
Definition: Type.h:741
StmtResult ActOnCapturedRegionEnd(Stmt *S)
Definition: SemaStmt.cpp:3909
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:178
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:618
C-style initialization with assignment.
Definition: Decl.h:709
This file defines OpenMP nodes for declarative directives.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:32
OMPClause * ActOnOpenMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
CanQualType VoidTy
Definition: ASTContext.h:881
Describes the kind of initialization being performed, along with location information for tokens rela...
This declaration is only a declaration.
Definition: Decl.h:997
ThreadStorageClassSpecifier getTSCSpec() const
Definition: Decl.h:884
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
Definition: Expr.h:164
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:5706
SourceLocation getBeginLoc() const
Definition: DeclSpec.h:72
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:124
Updates[]
Definition: OpenMPClause.h:310
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
bool isFileContext() const
Definition: DeclBase.h:1265
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:1840
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1167
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
Definition: Sema.cpp:1517
Expr * LB
LowerBound - local variable passed to runtime.
Definition: StmtOpenMP.h:504
void clear(unsigned Size)
Initialize all the fields to null.
Definition: StmtOpenMP.h:536
Expr * Init
Loop iteration variable init.
Definition: StmtOpenMP.h:498
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
#define DSAStack
Definition: SemaOpenMP.cpp:773
SourceLocation getLocStart() const LLVM_READONLY
Definition: Expr.cpp:427
bool isDynamicClass() const
Definition: DeclCXX.h:693
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:193
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause * > Clauses)
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId)
Called on well-formed 'reduction' clause.
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:458
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:385
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Definition: Decl.h:1207
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
QualType getType() const
Definition: Expr.h:125
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
* Finals[]
Definition: OpenMPClause.h:311
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
Definition: OpenMPKinds.h:66
This represents 'device' clause in the '#pragma omp ...' directive.
SourceLocation getLocStart() const LLVM_READONLY
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1121
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Definition: StmtOpenMP.h:520
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:22
static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:3893
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
bool isInvalidDecl() const
Definition: DeclBase.h:509
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
bool isUsed(bool CheckUsedAttr=true) const
Whether this declaration was used, meaning that a definition is required.
Definition: DeclBase.cpp:332
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:1911
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
Definition: Expr.h:246
This represents clause 'linear' in the '#pragma omp ...' directives.
SourceLocation getLocStart() const LLVM_READONLY
Definition: Decl.h:624
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause * > Clauses)
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Definition: StmtOpenMP.h:1205
bool IsOpenMPCapturedByRef(VarDecl *VD, const sema::CapturedRegionScopeInfo *RSI)
Return true if the provided declaration VD should be captured by reference in the provided scope RSI...
Definition: SemaOpenMP.cpp:775
bool hasAttrs() const
Definition: DeclBase.h:439
StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
detail::InMemoryDirectory::const_iterator E
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Sema/Lookup.h:249
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate', 'copyin' or 'copyprivate'.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Definition: Expr.cpp:2551
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:5255
bool IsOpenMPCapturedVar(VarDecl *VD)
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
Definition: SemaOpenMP.cpp:863
bool empty() const
Return true if no decls were found.
Definition: Sema/Lookup.h:280
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement...
Not an overloaded operator.
Definition: OperatorKinds.h:23
Expr * getSafelen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:381
Complex values, per C99 6.2.5p11.
Definition: Type.h:2087
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:5675
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2049
QualType getCanonicalType() const
Definition: Type.h:5128
This file defines OpenMP AST classes for executable directives and clauses.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, bool IsDecltype=false)
Definition: SemaExpr.cpp:12460
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Definition: Diagnostic.cpp:180
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S'...
Definition: SemaDecl.cpp:1268
bool isOpenMPTargetDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target-kind directive.
Expr * Inc
Loop increment.
Definition: StmtOpenMP.h:500
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Definition: OpenMPKinds.h:58
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:173
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
Definition: Diagnostic.cpp:102
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2287
bool isNRVOVariable() const
Determine whether this local variable can be used with the named return value optimization (NRVO)...
Definition: Decl.h:1158
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1522
InitializationStyle getInitStyle() const
The style of initialization for this declaration.
Definition: Decl.h:1129
QualType withRestrict() const
Definition: Type.h:757
OpenMPDefaultClauseKind
OpenMP attributes for 'default' clause.
Definition: OpenMPKinds.h:42
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1257
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:267
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:2914
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:986
This represents 'write' clause in the '#pragma omp atomic' directive.
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
Definition: ASTContext.h:947
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
Definition: OpenMPKinds.cpp:31
bool isUsable() const
Definition: Ownership.h:160
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
Definition: DeclBase.cpp:343
QualType getPointeeType() const
Definition: Type.h:2308
bool isTLSSupported() const
Whether the target supports thread-local storage.
bool isCXXForRangeDecl() const
Determine whether this variable is the for-range-declaration in a C++0x for-range statement...
Definition: Decl.h:1168
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:11761
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition: Stmt.cpp:1074
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Definition: Sema.h:286
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:483
Expr * UB
UpperBound - local variable passed to runtime.
Definition: StmtOpenMP.h:506
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
Describes the sequence of initializations required to initialize a given object or reference with a s...
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:5169
This represents 'nowait' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:903
void setEnd(SourceLocation e)
Represents a C++ struct/union/class.
Definition: DeclCXX.h:285
void setTSCSpec(ThreadStorageClassSpecifier TSC)
Definition: Decl.h:880
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
Opcode getOpcode() const
Definition: Expr.h:2918
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:498
Privates[]
Gets the list of initial values for linear variables.
Definition: OpenMPClause.h:310
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Definition: OpenMPKinds.h:91
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
Definition: DeclBase.cpp:1231
Do not present this diagnostic, ignore it.
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:307
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:220
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition: Decl.h:1189
bool isArrayType() const
Definition: Type.h:5344
Defines the clang::TargetInfo interface.
Expr * getRHS() const
Definition: Expr.h:2923
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
Definition: DeclBase.h:1316
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:526
ExprResult ExprError()
Definition: Ownership.h:267
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S)
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
Definition: SemaOpenMP.cpp:558
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:512
static OpaquePtr make(PtrTy P)
Definition: Ownership.h:54
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Definition: DeclSpec.h:196
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:922
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Definition: Expr.h:400
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable...
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:1880
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Sema/Lookup.h:523
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:106
static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, const VarDecl *VD, DSAStackTy::DSAVarData DVar, bool IsLoopIterVar=false)
static bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen, const Expr *Safelen)
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
Definition: StmtOpenMP.h:502
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
Definition: DeclBase.h:384
ASTContext & Context
Definition: Sema.h:295
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, std::unique_ptr< CorrectionCandidateCallback > CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
NamedDecl - This represents a decl with a name.
Definition: Decl.h:145
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:547
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:592
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:423
bool isArithmeticType() const
Definition: Type.cpp:1808
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
Directive - Abstract class representing a parsed verify directive.
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:10876
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Definition: Type.cpp:1730
Describes an entity that is being initialized.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
SourceLocation ColonLoc
Location of ':'.
Definition: OpenMPClause.h:266
static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
This represents '#pragma omp threadprivate ...' directive.
Definition: DeclOpenMP.h:36
bool isIntegralType(ASTContext &Ctx) const
Determine whether this type is an integral type.
Definition: Type.cpp:1619
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:57
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:5568
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
Definition: Decl.h:891
Helper class that creates diagnostics with optional template instantiation stacks.
Definition: Sema.h:1071
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Definition: Expr.cpp:2433
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
bool isPointerType() const
Definition: Type.h:5305
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.