clang  3.9.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"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclCXX.h"
21 #include "clang/AST/DeclOpenMP.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
27 #include "clang/Basic/TargetInfo.h"
28 #include "clang/Lex/Preprocessor.h"
30 #include "clang/Sema/Lookup.h"
31 #include "clang/Sema/Scope.h"
32 #include "clang/Sema/ScopeInfo.h"
34 using namespace clang;
35 
36 //===----------------------------------------------------------------------===//
37 // Stack of data-sharing attributes for variables
38 //===----------------------------------------------------------------------===//
39 
40 namespace {
41 /// \brief Default data sharing attributes, which can be applied to directive.
43  DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
44  DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'.
45  DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'.
46 };
47 
48 /// \brief Stack for tracking declarations used in OpenMP directives and
49 /// clauses and their data-sharing attributes.
50 class DSAStackTy final {
51 public:
52  struct DSAVarData final {
55  Expr *RefExpr = nullptr;
56  DeclRefExpr *PrivateCopy = nullptr;
57  SourceLocation ImplicitDSALoc;
58  DSAVarData() {}
59  };
61  OperatorOffsetTy;
62 
63 private:
64  struct DSAInfo final {
65  OpenMPClauseKind Attributes = OMPC_unknown;
66  /// Pointer to a reference expression and a flag which shows that the
67  /// variable is marked as lastprivate(true) or not (false).
68  llvm::PointerIntPair<Expr *, 1, bool> RefExpr;
69  DeclRefExpr *PrivateCopy = nullptr;
70  };
71  typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy;
72  typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy;
73  typedef std::pair<unsigned, VarDecl *> LCDeclInfo;
74  typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy;
75  typedef llvm::DenseMap<
77  MappedExprComponentsTy;
78  typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
79  CriticalsWithHintsTy;
80  typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>
81  DoacrossDependMapTy;
82 
83  struct SharingMapTy final {
84  DeclSAMapTy SharingMap;
85  AlignedMapTy AlignedMap;
86  MappedExprComponentsTy MappedExprComponents;
87  LoopControlVariablesMapTy LCVMap;
88  DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
89  SourceLocation DefaultAttrLoc;
91  DeclarationNameInfo DirectiveName;
92  Scope *CurScope = nullptr;
93  SourceLocation ConstructLoc;
94  /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
95  /// get the data (loop counters etc.) about enclosing loop-based construct.
96  /// This data is required during codegen.
97  DoacrossDependMapTy DoacrossDepends;
98  /// \brief first argument (Expr *) contains optional argument of the
99  /// 'ordered' clause, the second one is true if the regions has 'ordered'
100  /// clause, false otherwise.
101  llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
102  bool NowaitRegion = false;
103  bool CancelRegion = false;
104  unsigned AssociatedLoops = 1;
105  SourceLocation InnerTeamsRegionLoc;
106  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
107  Scope *CurScope, SourceLocation Loc)
108  : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
109  ConstructLoc(Loc) {}
110  SharingMapTy() {}
111  };
112 
113  typedef SmallVector<SharingMapTy, 4> StackTy;
114 
115  /// \brief Stack of used declaration and their data-sharing attributes.
116  StackTy Stack;
117  /// \brief true, if check for DSA must be from parent directive, false, if
118  /// from current directive.
119  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
120  Sema &SemaRef;
121  bool ForceCapturing = false;
122  CriticalsWithHintsTy Criticals;
123 
124  typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
125 
126  DSAVarData getDSA(StackTy::reverse_iterator& Iter, ValueDecl *D);
127 
128  /// \brief Checks if the variable is a local for OpenMP region.
129  bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
130 
131 public:
132  explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {}
133 
134  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
135  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
136 
137  bool isForceVarCapturing() const { return ForceCapturing; }
138  void setForceVarCapturing(bool V) { ForceCapturing = V; }
139 
140  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
141  Scope *CurScope, SourceLocation Loc) {
142  Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
143  Stack.back().DefaultAttrLoc = Loc;
144  }
145 
146  void pop() {
147  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!");
148  Stack.pop_back();
149  }
150 
151  void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) {
152  Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint);
153  }
154  const std::pair<OMPCriticalDirective *, llvm::APSInt>
155  getCriticalWithHint(const DeclarationNameInfo &Name) const {
156  auto I = Criticals.find(Name.getAsString());
157  if (I != Criticals.end())
158  return I->second;
159  return std::make_pair(nullptr, llvm::APSInt());
160  }
161  /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
162  /// add it and return NULL; otherwise return previous occurrence's expression
163  /// for diagnostics.
164  Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE);
165 
166  /// \brief Register specified variable as loop control variable.
167  void addLoopControlVariable(ValueDecl *D, VarDecl *Capture);
168  /// \brief Check if the specified variable is a loop control variable for
169  /// current region.
170  /// \return The index of the loop control variable in the list of associated
171  /// for-loops (from outer to inner).
172  LCDeclInfo isLoopControlVariable(ValueDecl *D);
173  /// \brief Check if the specified variable is a loop control variable for
174  /// parent region.
175  /// \return The index of the loop control variable in the list of associated
176  /// for-loops (from outer to inner).
177  LCDeclInfo isParentLoopControlVariable(ValueDecl *D);
178  /// \brief Get the loop control variable for the I-th loop (or nullptr) in
179  /// parent directive.
180  ValueDecl *getParentLoopControlVariable(unsigned I);
181 
182  /// \brief Adds explicit data sharing attribute to the specified declaration.
183  void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
184  DeclRefExpr *PrivateCopy = nullptr);
185 
186  /// \brief Returns data sharing attributes from top of the stack for the
187  /// specified declaration.
188  DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
189  /// \brief Returns data-sharing attributes for the specified declaration.
190  DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent);
191  /// \brief Checks if the specified variables has data-sharing attributes which
192  /// match specified \a CPred predicate in any directive which matches \a DPred
193  /// predicate.
194  DSAVarData hasDSA(ValueDecl *D,
195  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
196  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
197  bool FromParent);
198  /// \brief Checks if the specified variables has data-sharing attributes which
199  /// match specified \a CPred predicate in any innermost directive which
200  /// matches \a DPred predicate.
201  DSAVarData
202  hasInnermostDSA(ValueDecl *D,
203  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
204  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
205  bool FromParent);
206  /// \brief Checks if the specified variables has explicit data-sharing
207  /// attributes which match specified \a CPred predicate at the specified
208  /// OpenMP region.
209  bool hasExplicitDSA(ValueDecl *D,
210  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
211  unsigned Level, bool NotLastprivate = false);
212 
213  /// \brief Returns true if the directive at level \Level matches in the
214  /// specified \a DPred predicate.
215  bool hasExplicitDirective(
216  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
217  unsigned Level);
218 
219  /// \brief Finds a directive which matches specified \a DPred predicate.
220  bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind,
221  const DeclarationNameInfo &,
222  SourceLocation)> &DPred,
223  bool FromParent);
224 
225  /// \brief Returns currently analyzed directive.
226  OpenMPDirectiveKind getCurrentDirective() const {
227  return Stack.back().Directive;
228  }
229  /// \brief Returns parent directive.
230  OpenMPDirectiveKind getParentDirective() const {
231  if (Stack.size() > 2)
232  return Stack[Stack.size() - 2].Directive;
233  return OMPD_unknown;
234  }
235 
236  /// \brief Set default data sharing attribute to none.
237  void setDefaultDSANone(SourceLocation Loc) {
238  Stack.back().DefaultAttr = DSA_none;
239  Stack.back().DefaultAttrLoc = Loc;
240  }
241  /// \brief Set default data sharing attribute to shared.
242  void setDefaultDSAShared(SourceLocation Loc) {
243  Stack.back().DefaultAttr = DSA_shared;
244  Stack.back().DefaultAttrLoc = Loc;
245  }
246 
247  DefaultDataSharingAttributes getDefaultDSA() const {
248  return Stack.back().DefaultAttr;
249  }
250  SourceLocation getDefaultDSALocation() const {
251  return Stack.back().DefaultAttrLoc;
252  }
253 
254  /// \brief Checks if the specified variable is a threadprivate.
255  bool isThreadPrivate(VarDecl *D) {
256  DSAVarData DVar = getTopDSA(D, false);
257  return isOpenMPThreadPrivate(DVar.CKind);
258  }
259 
260  /// \brief Marks current region as ordered (it has an 'ordered' clause).
261  void setOrderedRegion(bool IsOrdered, Expr *Param) {
262  Stack.back().OrderedRegion.setInt(IsOrdered);
263  Stack.back().OrderedRegion.setPointer(Param);
264  }
265  /// \brief Returns true, if parent region is ordered (has associated
266  /// 'ordered' clause), false - otherwise.
267  bool isParentOrderedRegion() const {
268  if (Stack.size() > 2)
269  return Stack[Stack.size() - 2].OrderedRegion.getInt();
270  return false;
271  }
272  /// \brief Returns optional parameter for the ordered region.
273  Expr *getParentOrderedRegionParam() const {
274  if (Stack.size() > 2)
275  return Stack[Stack.size() - 2].OrderedRegion.getPointer();
276  return nullptr;
277  }
278  /// \brief Marks current region as nowait (it has a 'nowait' clause).
279  void setNowaitRegion(bool IsNowait = true) {
280  Stack.back().NowaitRegion = IsNowait;
281  }
282  /// \brief Returns true, if parent region is nowait (has associated
283  /// 'nowait' clause), false - otherwise.
284  bool isParentNowaitRegion() const {
285  if (Stack.size() > 2)
286  return Stack[Stack.size() - 2].NowaitRegion;
287  return false;
288  }
289  /// \brief Marks parent region as cancel region.
290  void setParentCancelRegion(bool Cancel = true) {
291  if (Stack.size() > 2)
292  Stack[Stack.size() - 2].CancelRegion =
293  Stack[Stack.size() - 2].CancelRegion || Cancel;
294  }
295  /// \brief Return true if current region has inner cancel construct.
296  bool isCancelRegion() const {
297  return Stack.back().CancelRegion;
298  }
299 
300  /// \brief Set collapse value for the region.
301  void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; }
302  /// \brief Return collapse value for region.
303  unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; }
304 
305  /// \brief Marks current target region as one with closely nested teams
306  /// region.
307  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
308  if (Stack.size() > 2)
309  Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc;
310  }
311  /// \brief Returns true, if current region has closely nested teams region.
312  bool hasInnerTeamsRegion() const {
313  return getInnerTeamsRegionLoc().isValid();
314  }
315  /// \brief Returns location of the nested teams region (if any).
316  SourceLocation getInnerTeamsRegionLoc() const {
317  if (Stack.size() > 1)
318  return Stack.back().InnerTeamsRegionLoc;
319  return SourceLocation();
320  }
321 
322  Scope *getCurScope() const { return Stack.back().CurScope; }
323  Scope *getCurScope() { return Stack.back().CurScope; }
324  SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
325 
326  // Do the check specified in \a Check to all component lists and return true
327  // if any issue is found.
328  bool checkMappableExprComponentListsForDecl(
329  ValueDecl *VD, bool CurrentRegionOnly,
330  const llvm::function_ref<bool(
332  auto SI = Stack.rbegin();
333  auto SE = Stack.rend();
334 
335  if (SI == SE)
336  return false;
337 
338  if (CurrentRegionOnly) {
339  SE = std::next(SI);
340  } else {
341  ++SI;
342  }
343 
344  for (; SI != SE; ++SI) {
345  auto MI = SI->MappedExprComponents.find(VD);
346  if (MI != SI->MappedExprComponents.end())
347  for (auto &L : MI->second)
348  if (Check(L))
349  return true;
350  }
351  return false;
352  }
353 
354  // Create a new mappable expression component list associated with a given
355  // declaration and initialize it with the provided list of components.
356  void addMappableExpressionComponents(
357  ValueDecl *VD,
359  assert(Stack.size() > 1 &&
360  "Not expecting to retrieve components from a empty stack!");
361  auto &MEC = Stack.back().MappedExprComponents[VD];
362  // Create new entry and append the new components there.
363  MEC.resize(MEC.size() + 1);
364  MEC.back().append(Components.begin(), Components.end());
365  }
366 
367  unsigned getNestingLevel() const {
368  assert(Stack.size() > 1);
369  return Stack.size() - 2;
370  }
371  void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) {
372  assert(Stack.size() > 2);
373  assert(isOpenMPWorksharingDirective(Stack[Stack.size() - 2].Directive));
374  Stack[Stack.size() - 2].DoacrossDepends.insert({C, OpsOffs});
375  }
376  llvm::iterator_range<DoacrossDependMapTy::const_iterator>
377  getDoacrossDependClauses() const {
378  assert(Stack.size() > 1);
379  if (isOpenMPWorksharingDirective(Stack[Stack.size() - 1].Directive)) {
380  auto &Ref = Stack[Stack.size() - 1].DoacrossDepends;
381  return llvm::make_range(Ref.begin(), Ref.end());
382  }
383  return llvm::make_range(Stack[0].DoacrossDepends.end(),
384  Stack[0].DoacrossDepends.end());
385  }
386 };
387 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
388  return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
389  isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
390 }
391 } // namespace
392 
394  auto *VD = dyn_cast<VarDecl>(D);
395  auto *FD = dyn_cast<FieldDecl>(D);
396  if (VD != nullptr) {
397  VD = VD->getCanonicalDecl();
398  D = VD;
399  } else {
400  assert(FD);
401  FD = FD->getCanonicalDecl();
402  D = FD;
403  }
404  return D;
405 }
406 
407 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator& Iter,
408  ValueDecl *D) {
409  D = getCanonicalDecl(D);
410  auto *VD = dyn_cast<VarDecl>(D);
411  auto *FD = dyn_cast<FieldDecl>(D);
412  DSAVarData DVar;
413  if (Iter == std::prev(Stack.rend())) {
414  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
415  // in a region but not in construct]
416  // File-scope or namespace-scope variables referenced in called routines
417  // in the region are shared unless they appear in a threadprivate
418  // directive.
419  if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
420  DVar.CKind = OMPC_shared;
421 
422  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
423  // in a region but not in construct]
424  // Variables with static storage duration that are declared in called
425  // routines in the region are shared.
426  if (VD && VD->hasGlobalStorage())
427  DVar.CKind = OMPC_shared;
428 
429  // Non-static data members are shared by default.
430  if (FD)
431  DVar.CKind = OMPC_shared;
432 
433  return DVar;
434  }
435 
436  DVar.DKind = Iter->Directive;
437  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
438  // in a Construct, C/C++, predetermined, p.1]
439  // Variables with automatic storage duration that are declared in a scope
440  // inside the construct are private.
441  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
442  (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
443  DVar.CKind = OMPC_private;
444  return DVar;
445  }
446 
447  // Explicitly specified attributes and local variables with predetermined
448  // attributes.
449  if (Iter->SharingMap.count(D)) {
450  DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer();
451  DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy;
452  DVar.CKind = Iter->SharingMap[D].Attributes;
453  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
454  return DVar;
455  }
456 
457  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
458  // in a Construct, C/C++, implicitly determined, p.1]
459  // In a parallel or task construct, the data-sharing attributes of these
460  // variables are determined by the default clause, if present.
461  switch (Iter->DefaultAttr) {
462  case DSA_shared:
463  DVar.CKind = OMPC_shared;
464  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
465  return DVar;
466  case DSA_none:
467  return DVar;
468  case DSA_unspecified:
469  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
470  // in a Construct, implicitly determined, p.2]
471  // In a parallel construct, if no default clause is present, these
472  // variables are shared.
473  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
474  if (isOpenMPParallelDirective(DVar.DKind) ||
475  isOpenMPTeamsDirective(DVar.DKind)) {
476  DVar.CKind = OMPC_shared;
477  return DVar;
478  }
479 
480  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
481  // in a Construct, implicitly determined, p.4]
482  // In a task construct, if no default clause is present, a variable that in
483  // the enclosing context is determined to be shared by all implicit tasks
484  // bound to the current team is shared.
485  if (isOpenMPTaskingDirective(DVar.DKind)) {
486  DSAVarData DVarTemp;
487  for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend();
488  I != EE; ++I) {
489  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
490  // Referenced in a Construct, implicitly determined, p.6]
491  // In a task construct, if no default clause is present, a variable
492  // whose data-sharing attribute is not determined by the rules above is
493  // firstprivate.
494  DVarTemp = getDSA(I, D);
495  if (DVarTemp.CKind != OMPC_shared) {
496  DVar.RefExpr = nullptr;
497  DVar.CKind = OMPC_firstprivate;
498  return DVar;
499  }
500  if (isParallelOrTaskRegion(I->Directive))
501  break;
502  }
503  DVar.CKind =
504  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
505  return DVar;
506  }
507  }
508  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
509  // in a Construct, implicitly determined, p.3]
510  // For constructs other than task, if no default clause is present, these
511  // variables inherit their data-sharing attributes from the enclosing
512  // context.
513  return getDSA(++Iter, D);
514 }
515 
516 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) {
517  assert(Stack.size() > 1 && "Data sharing attributes stack is empty");
518  D = getCanonicalDecl(D);
519  auto It = Stack.back().AlignedMap.find(D);
520  if (It == Stack.back().AlignedMap.end()) {
521  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
522  Stack.back().AlignedMap[D] = NewDE;
523  return nullptr;
524  } else {
525  assert(It->second && "Unexpected nullptr expr in the aligned map");
526  return It->second;
527  }
528  return nullptr;
529 }
530 
531 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) {
532  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
533  D = getCanonicalDecl(D);
534  Stack.back().LCVMap.insert(
535  std::make_pair(D, LCDeclInfo(Stack.back().LCVMap.size() + 1, Capture)));
536 }
537 
538 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) {
539  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
540  D = getCanonicalDecl(D);
541  return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D]
542  : LCDeclInfo(0, nullptr);
543 }
544 
545 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) {
546  assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");
547  D = getCanonicalDecl(D);
548  return Stack[Stack.size() - 2].LCVMap.count(D) > 0
549  ? Stack[Stack.size() - 2].LCVMap[D]
550  : LCDeclInfo(0, nullptr);
551 }
552 
553 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) {
554  assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");
555  if (Stack[Stack.size() - 2].LCVMap.size() < I)
556  return nullptr;
557  for (auto &Pair : Stack[Stack.size() - 2].LCVMap) {
558  if (Pair.second.first == I)
559  return Pair.first;
560  }
561  return nullptr;
562 }
563 
564 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
565  DeclRefExpr *PrivateCopy) {
566  D = getCanonicalDecl(D);
567  if (A == OMPC_threadprivate) {
568  auto &Data = Stack[0].SharingMap[D];
569  Data.Attributes = A;
570  Data.RefExpr.setPointer(E);
571  Data.PrivateCopy = nullptr;
572  } else {
573  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
574  auto &Data = Stack.back().SharingMap[D];
575  assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
576  (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
577  (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
578  (isLoopControlVariable(D).first && A == OMPC_private));
579  if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
580  Data.RefExpr.setInt(/*IntVal=*/true);
581  return;
582  }
583  const bool IsLastprivate =
584  A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
585  Data.Attributes = A;
586  Data.RefExpr.setPointerAndInt(E, IsLastprivate);
587  Data.PrivateCopy = PrivateCopy;
588  if (PrivateCopy) {
589  auto &Data = Stack.back().SharingMap[PrivateCopy->getDecl()];
590  Data.Attributes = A;
591  Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
592  Data.PrivateCopy = nullptr;
593  }
594  }
595 }
596 
597 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
598  D = D->getCanonicalDecl();
599  if (Stack.size() > 2) {
600  reverse_iterator I = Iter, E = std::prev(Stack.rend());
601  Scope *TopScope = nullptr;
602  while (I != E && !isParallelOrTaskRegion(I->Directive)) {
603  ++I;
604  }
605  if (I == E)
606  return false;
607  TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
608  Scope *CurScope = getCurScope();
609  while (CurScope != TopScope && !CurScope->isDeclScope(D)) {
610  CurScope = CurScope->getParent();
611  }
612  return CurScope != TopScope;
613  }
614  return false;
615 }
616 
617 /// \brief Build a variable declaration for OpenMP loop iteration variable.
619  StringRef Name, const AttrVec *Attrs = nullptr) {
620  DeclContext *DC = SemaRef.CurContext;
621  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
622  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
623  VarDecl *Decl =
624  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
625  if (Attrs) {
626  for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
627  I != E; ++I)
628  Decl->addAttr(*I);
629  }
630  Decl->setImplicit();
631  return Decl;
632 }
633 
635  SourceLocation Loc,
636  bool RefersToCapture = false) {
637  D->setReferenced();
638  D->markUsed(S.Context);
640  SourceLocation(), D, RefersToCapture, Loc, Ty,
641  VK_LValue);
642 }
643 
644 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) {
645  D = getCanonicalDecl(D);
646  DSAVarData DVar;
647 
648  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
649  // in a Construct, C/C++, predetermined, p.1]
650  // Variables appearing in threadprivate directives are threadprivate.
651  auto *VD = dyn_cast<VarDecl>(D);
652  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
653  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
654  SemaRef.getLangOpts().OpenMPUseTLS &&
655  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
656  (VD && VD->getStorageClass() == SC_Register &&
657  VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
658  addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
659  D->getLocation()),
661  }
662  if (Stack[0].SharingMap.count(D)) {
663  DVar.RefExpr = Stack[0].SharingMap[D].RefExpr.getPointer();
664  DVar.CKind = OMPC_threadprivate;
665  return DVar;
666  }
667 
668  if (Stack.size() == 1) {
669  // Not in OpenMP execution region and top scope was already checked.
670  return DVar;
671  }
672 
673  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
674  // in a Construct, C/C++, predetermined, p.4]
675  // Static data members are shared.
676  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
677  // in a Construct, C/C++, predetermined, p.7]
678  // Variables with static storage duration that are declared in a scope
679  // inside the construct are shared.
680  auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; };
681  if (VD && VD->isStaticDataMember()) {
682  DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
683  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
684  return DVar;
685 
686  DVar.CKind = OMPC_shared;
687  return DVar;
688  }
689 
691  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
692  Type = SemaRef.getASTContext().getBaseElementType(Type);
693  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
694  // in a Construct, C/C++, predetermined, p.6]
695  // Variables with const qualified type having no mutable member are
696  // shared.
697  CXXRecordDecl *RD =
698  SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
699  if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
700  if (auto *CTD = CTSD->getSpecializedTemplate())
701  RD = CTD->getTemplatedDecl();
702  if (IsConstant &&
703  !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
704  RD->hasMutableFields())) {
705  // Variables with const-qualified type having no mutable member may be
706  // listed in a firstprivate clause, even if they are static data members.
707  DSAVarData DVarTemp = hasDSA(
708  D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; },
709  MatchesAlways, FromParent);
710  if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
711  return DVar;
712 
713  DVar.CKind = OMPC_shared;
714  return DVar;
715  }
716 
717  // Explicitly specified attributes and local variables with predetermined
718  // attributes.
719  auto StartI = std::next(Stack.rbegin());
720  auto EndI = std::prev(Stack.rend());
721  if (FromParent && StartI != EndI) {
722  StartI = std::next(StartI);
723  }
724  auto I = std::prev(StartI);
725  if (I->SharingMap.count(D)) {
726  DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer();
727  DVar.PrivateCopy = I->SharingMap[D].PrivateCopy;
728  DVar.CKind = I->SharingMap[D].Attributes;
729  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
730  }
731 
732  return DVar;
733 }
734 
735 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
736  bool FromParent) {
737  D = getCanonicalDecl(D);
738  auto StartI = Stack.rbegin();
739  auto EndI = std::prev(Stack.rend());
740  if (FromParent && StartI != EndI) {
741  StartI = std::next(StartI);
742  }
743  return getDSA(StartI, D);
744 }
745 
746 DSAStackTy::DSAVarData
747 DSAStackTy::hasDSA(ValueDecl *D,
748  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
749  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
750  bool FromParent) {
751  D = getCanonicalDecl(D);
752  auto StartI = std::next(Stack.rbegin());
753  auto EndI = Stack.rend();
754  if (FromParent && StartI != EndI) {
755  StartI = std::next(StartI);
756  }
757  for (auto I = StartI, EE = EndI; I != EE; ++I) {
758  if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
759  continue;
760  DSAVarData DVar = getDSA(I, D);
761  if (CPred(DVar.CKind))
762  return DVar;
763  }
764  return DSAVarData();
765 }
766 
767 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
768  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
769  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
770  bool FromParent) {
771  D = getCanonicalDecl(D);
772  auto StartI = std::next(Stack.rbegin());
773  auto EndI = Stack.rend();
774  if (FromParent && StartI != EndI) {
775  StartI = std::next(StartI);
776  }
777  for (auto I = StartI, EE = EndI; I != EE; ++I) {
778  if (!DPred(I->Directive))
779  break;
780  DSAVarData DVar = getDSA(I, D);
781  if (CPred(DVar.CKind))
782  return DVar;
783  return DSAVarData();
784  }
785  return DSAVarData();
786 }
787 
788 bool DSAStackTy::hasExplicitDSA(
789  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
790  unsigned Level, bool NotLastprivate) {
791  if (CPred(ClauseKindMode))
792  return true;
793  D = getCanonicalDecl(D);
794  auto StartI = std::next(Stack.begin());
795  auto EndI = Stack.end();
796  if (std::distance(StartI, EndI) <= (int)Level)
797  return false;
798  std::advance(StartI, Level);
799  return (StartI->SharingMap.count(D) > 0) &&
800  StartI->SharingMap[D].RefExpr.getPointer() &&
801  CPred(StartI->SharingMap[D].Attributes) &&
802  (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt());
803 }
804 
805 bool DSAStackTy::hasExplicitDirective(
806  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
807  unsigned Level) {
808  auto StartI = std::next(Stack.begin());
809  auto EndI = Stack.end();
810  if (std::distance(StartI, EndI) <= (int)Level)
811  return false;
812  std::advance(StartI, Level);
813  return DPred(StartI->Directive);
814 }
815 
816 bool DSAStackTy::hasDirective(
817  const llvm::function_ref<bool(OpenMPDirectiveKind,
819  &DPred,
820  bool FromParent) {
821  // We look only in the enclosing region.
822  if (Stack.size() < 2)
823  return false;
824  auto StartI = std::next(Stack.rbegin());
825  auto EndI = std::prev(Stack.rend());
826  if (FromParent && StartI != EndI) {
827  StartI = std::next(StartI);
828  }
829  for (auto I = StartI, EE = EndI; I != EE; ++I) {
830  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
831  return true;
832  }
833  return false;
834 }
835 
836 void Sema::InitDataSharingAttributesStack() {
837  VarDataSharingAttributesStack = new DSAStackTy(*this);
838 }
839 
840 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
841 
842 bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) {
843  assert(LangOpts.OpenMP && "OpenMP is not allowed");
844 
845  auto &Ctx = getASTContext();
846  bool IsByRef = true;
847 
848  // Find the directive that is associated with the provided scope.
849  auto Ty = D->getType();
850 
851  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
852  // This table summarizes how a given variable should be passed to the device
853  // given its type and the clauses where it appears. This table is based on
854  // the description in OpenMP 4.5 [2.10.4, target Construct] and
855  // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
856  //
857  // =========================================================================
858  // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
859  // | |(tofrom:scalar)| | pvt | | | |
860  // =========================================================================
861  // | scl | | | | - | | bycopy|
862  // | scl | | - | x | - | - | bycopy|
863  // | scl | | x | - | - | - | null |
864  // | scl | x | | | - | | byref |
865  // | scl | x | - | x | - | - | bycopy|
866  // | scl | x | x | - | - | - | null |
867  // | scl | | - | - | - | x | byref |
868  // | scl | x | - | - | - | x | byref |
869  //
870  // | agg | n.a. | | | - | | byref |
871  // | agg | n.a. | - | x | - | - | byref |
872  // | agg | n.a. | x | - | - | - | null |
873  // | agg | n.a. | - | - | - | x | byref |
874  // | agg | n.a. | - | - | - | x[] | byref |
875  //
876  // | ptr | n.a. | | | - | | bycopy|
877  // | ptr | n.a. | - | x | - | - | bycopy|
878  // | ptr | n.a. | x | - | - | - | null |
879  // | ptr | n.a. | - | - | - | x | byref |
880  // | ptr | n.a. | - | - | - | x[] | bycopy|
881  // | ptr | n.a. | - | - | x | | bycopy|
882  // | ptr | n.a. | - | - | x | x | bycopy|
883  // | ptr | n.a. | - | - | x | x[] | bycopy|
884  // =========================================================================
885  // Legend:
886  // scl - scalar
887  // ptr - pointer
888  // agg - aggregate
889  // x - applies
890  // - - invalid in this combination
891  // [] - mapped with an array section
892  // byref - should be mapped by reference
893  // byval - should be mapped by value
894  // null - initialize a local variable to null on the device
895  //
896  // Observations:
897  // - All scalar declarations that show up in a map clause have to be passed
898  // by reference, because they may have been mapped in the enclosing data
899  // environment.
900  // - If the scalar value does not fit the size of uintptr, it has to be
901  // passed by reference, regardless the result in the table above.
902  // - For pointers mapped by value that have either an implicit map or an
903  // array section, the runtime library may pass the NULL value to the
904  // device instead of the value passed to it by the compiler.
905 
906 
907  if (Ty->isReferenceType())
908  Ty = Ty->castAs<ReferenceType>()->getPointeeType();
909 
910  // Locate map clauses and see if the variable being captured is referred to
911  // in any of those clauses. Here we only care about variables, not fields,
912  // because fields are part of aggregates.
913  bool IsVariableUsedInMapClause = false;
914  bool IsVariableAssociatedWithSection = false;
915 
916  DSAStack->checkMappableExprComponentListsForDecl(
917  D, /*CurrentRegionOnly=*/true,
919  MapExprComponents) {
920 
921  auto EI = MapExprComponents.rbegin();
922  auto EE = MapExprComponents.rend();
923 
924  assert(EI != EE && "Invalid map expression!");
925 
926  if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
927  IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
928 
929  ++EI;
930  if (EI == EE)
931  return false;
932 
933  if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
934  isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
935  isa<MemberExpr>(EI->getAssociatedExpression())) {
936  IsVariableAssociatedWithSection = true;
937  // There is nothing more we need to know about this variable.
938  return true;
939  }
940 
941  // Keep looking for more map info.
942  return false;
943  });
944 
945  if (IsVariableUsedInMapClause) {
946  // If variable is identified in a map clause it is always captured by
947  // reference except if it is a pointer that is dereferenced somehow.
948  IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
949  } else {
950  // By default, all the data that has a scalar type is mapped by copy.
951  IsByRef = !Ty->isScalarType();
952  }
953  }
954 
955  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
956  IsByRef = !DSAStack->hasExplicitDSA(
957  D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
958  Level, /*NotLastprivate=*/true);
959  }
960 
961  // When passing data by copy, we need to make sure it fits the uintptr size
962  // and alignment, because the runtime library only deals with uintptr types.
963  // If it does not fit the uintptr size, we need to pass the data by reference
964  // instead.
965  if (!IsByRef &&
966  (Ctx.getTypeSizeInChars(Ty) >
967  Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
968  Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
969  IsByRef = true;
970  }
971 
972  return IsByRef;
973 }
974 
975 unsigned Sema::getOpenMPNestingLevel() const {
976  assert(getLangOpts().OpenMP);
977  return DSAStack->getNestingLevel();
978 }
979 
981  assert(LangOpts.OpenMP && "OpenMP is not allowed");
982  D = getCanonicalDecl(D);
983 
984  // If we are attempting to capture a global variable in a directive with
985  // 'target' we return true so that this global is also mapped to the device.
986  //
987  // FIXME: If the declaration is enclosed in a 'declare target' directive,
988  // then it should not be captured. Therefore, an extra check has to be
989  // inserted here once support for 'declare target' is added.
990  //
991  auto *VD = dyn_cast<VarDecl>(D);
992  if (VD && !VD->hasLocalStorage()) {
993  if (DSAStack->getCurrentDirective() == OMPD_target &&
994  !DSAStack->isClauseParsingMode())
995  return VD;
996  if (DSAStack->hasDirective(
998  SourceLocation) -> bool {
1000  },
1001  false))
1002  return VD;
1003  }
1004 
1005  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1006  (!DSAStack->isClauseParsingMode() ||
1007  DSAStack->getParentDirective() != OMPD_unknown)) {
1008  auto &&Info = DSAStack->isLoopControlVariable(D);
1009  if (Info.first ||
1010  (VD && VD->hasLocalStorage() &&
1011  isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
1012  (VD && DSAStack->isForceVarCapturing()))
1013  return VD ? VD : Info.second;
1014  auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1015  if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1016  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1017  DVarPrivate = DSAStack->hasDSA(
1018  D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
1019  DSAStack->isClauseParsingMode());
1020  if (DVarPrivate.CKind != OMPC_unknown)
1021  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1022  }
1023  return nullptr;
1024 }
1025 
1026 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) {
1027  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1028  return DSAStack->hasExplicitDSA(
1029  D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level);
1030 }
1031 
1033  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1034  // Return true if the current level is no longer enclosed in a target region.
1035 
1036  auto *VD = dyn_cast<VarDecl>(D);
1037  return VD && !VD->hasLocalStorage() &&
1038  DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1039  Level);
1040 }
1041 
1042 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1043 
1045  const DeclarationNameInfo &DirName,
1046  Scope *CurScope, SourceLocation Loc) {
1047  DSAStack->push(DKind, DirName, CurScope, Loc);
1049 }
1050 
1052  DSAStack->setClauseParsingMode(K);
1053 }
1054 
1056  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1057 }
1058 
1059 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1060  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1061  // A variable of class type (or array thereof) that appears in a lastprivate
1062  // clause requires an accessible, unambiguous default constructor for the
1063  // class type, unless the list item is also specified in a firstprivate
1064  // clause.
1065  if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1066  for (auto *C : D->clauses()) {
1067  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1068  SmallVector<Expr *, 8> PrivateCopies;
1069  for (auto *DE : Clause->varlists()) {
1070  if (DE->isValueDependent() || DE->isTypeDependent()) {
1071  PrivateCopies.push_back(nullptr);
1072  continue;
1073  }
1074  auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1075  VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1076  QualType Type = VD->getType().getNonReferenceType();
1077  auto DVar = DSAStack->getTopDSA(VD, false);
1078  if (DVar.CKind == OMPC_lastprivate) {
1079  // Generate helper private variable and initialize it with the
1080  // default value. The address of the original variable is replaced
1081  // by the address of the new private variable in CodeGen. This new
1082  // variable is not added to IdResolver, so the code in the OpenMP
1083  // region uses original variable for proper diagnostics.
1084  auto *VDPrivate = buildVarDecl(
1085  *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1086  VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
1087  ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
1088  if (VDPrivate->isInvalidDecl())
1089  continue;
1090  PrivateCopies.push_back(buildDeclRefExpr(
1091  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1092  } else {
1093  // The variable is also a firstprivate, so initialization sequence
1094  // for private copy is generated already.
1095  PrivateCopies.push_back(nullptr);
1096  }
1097  }
1098  // Set initializers to private copies if no errors were found.
1099  if (PrivateCopies.size() == Clause->varlist_size())
1100  Clause->setPrivateCopies(PrivateCopies);
1101  }
1102  }
1103  }
1104 
1105  DSAStack->pop();
1108 }
1109 
1110 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1111  Expr *NumIterations, Sema &SemaRef,
1112  Scope *S, DSAStackTy *Stack);
1113 
1114 namespace {
1115 
1116 class VarDeclFilterCCC : public CorrectionCandidateCallback {
1117 private:
1118  Sema &SemaRef;
1119 
1120 public:
1121  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1122  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1123  NamedDecl *ND = Candidate.getCorrectionDecl();
1124  if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
1125  return VD->hasGlobalStorage() &&
1126  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1127  SemaRef.getCurScope());
1128  }
1129  return false;
1130  }
1131 };
1132 
1133 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback {
1134 private:
1135  Sema &SemaRef;
1136 
1137 public:
1138  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1139  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1140  NamedDecl *ND = Candidate.getCorrectionDecl();
1141  if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
1142  return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1143  SemaRef.getCurScope());
1144  }
1145  return false;
1146  }
1147 };
1148 
1149 } // namespace
1150 
1152  CXXScopeSpec &ScopeSpec,
1153  const DeclarationNameInfo &Id) {
1154  LookupResult Lookup(*this, Id, LookupOrdinaryName);
1155  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1156 
1157  if (Lookup.isAmbiguous())
1158  return ExprError();
1159 
1160  VarDecl *VD;
1161  if (!Lookup.isSingleResult()) {
1162  if (TypoCorrection Corrected = CorrectTypo(
1163  Id, LookupOrdinaryName, CurScope, nullptr,
1164  llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1165  diagnoseTypo(Corrected,
1166  PDiag(Lookup.empty()
1167  ? diag::err_undeclared_var_use_suggest
1168  : diag::err_omp_expected_var_arg_suggest)
1169  << Id.getName());
1170  VD = Corrected.getCorrectionDeclAs<VarDecl>();
1171  } else {
1172  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1173  : diag::err_omp_expected_var_arg)
1174  << Id.getName();
1175  return ExprError();
1176  }
1177  } else {
1178  if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1179  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1180  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1181  return ExprError();
1182  }
1183  }
1184  Lookup.suppressDiagnostics();
1185 
1186  // OpenMP [2.9.2, Syntax, C/C++]
1187  // Variables must be file-scope, namespace-scope, or static block-scope.
1188  if (!VD->hasGlobalStorage()) {
1189  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1190  << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1191  bool IsDecl =
1193  Diag(VD->getLocation(),
1194  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1195  << VD;
1196  return ExprError();
1197  }
1198 
1199  VarDecl *CanonicalVD = VD->getCanonicalDecl();
1200  NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1201  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1202  // A threadprivate directive for file-scope variables must appear outside
1203  // any definition or declaration.
1204  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1206  Diag(Id.getLoc(), diag::err_omp_var_scope)
1207  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1208  bool IsDecl =
1210  Diag(VD->getLocation(),
1211  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1212  << VD;
1213  return ExprError();
1214  }
1215  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1216  // A threadprivate directive for static class member variables must appear
1217  // in the class definition, in the same scope in which the member
1218  // variables are declared.
1219  if (CanonicalVD->isStaticDataMember() &&
1220  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1221  Diag(Id.getLoc(), diag::err_omp_var_scope)
1222  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1223  bool IsDecl =
1225  Diag(VD->getLocation(),
1226  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1227  << VD;
1228  return ExprError();
1229  }
1230  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1231  // A threadprivate directive for namespace-scope variables must appear
1232  // outside any definition or declaration other than the namespace
1233  // definition itself.
1234  if (CanonicalVD->getDeclContext()->isNamespace() &&
1236  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1237  Diag(Id.getLoc(), diag::err_omp_var_scope)
1238  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1239  bool IsDecl =
1241  Diag(VD->getLocation(),
1242  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1243  << VD;
1244  return ExprError();
1245  }
1246  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1247  // A threadprivate directive for static block-scope variables must appear
1248  // in the scope of the variable and not in a nested scope.
1249  if (CanonicalVD->isStaticLocal() && CurScope &&
1250  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1251  Diag(Id.getLoc(), diag::err_omp_var_scope)
1252  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1253  bool IsDecl =
1255  Diag(VD->getLocation(),
1256  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1257  << VD;
1258  return ExprError();
1259  }
1260 
1261  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1262  // A threadprivate directive must lexically precede all references to any
1263  // of the variables in its list.
1264  if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1265  Diag(Id.getLoc(), diag::err_omp_var_used)
1266  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1267  return ExprError();
1268  }
1269 
1270  QualType ExprType = VD->getType().getNonReferenceType();
1272  SourceLocation(), VD,
1273  /*RefersToEnclosingVariableOrCapture=*/false,
1274  Id.getLoc(), ExprType, VK_LValue);
1275 }
1276 
1279  ArrayRef<Expr *> VarList) {
1280  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1281  CurContext->addDecl(D);
1283  }
1284  return nullptr;
1285 }
1286 
1287 namespace {
1288 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1289  Sema &SemaRef;
1290 
1291 public:
1292  bool VisitDeclRefExpr(const DeclRefExpr *E) {
1293  if (auto VD = dyn_cast<VarDecl>(E->getDecl())) {
1294  if (VD->hasLocalStorage()) {
1295  SemaRef.Diag(E->getLocStart(),
1296  diag::err_omp_local_var_in_threadprivate_init)
1297  << E->getSourceRange();
1298  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1299  << VD << VD->getSourceRange();
1300  return true;
1301  }
1302  }
1303  return false;
1304  }
1305  bool VisitStmt(const Stmt *S) {
1306  for (auto Child : S->children()) {
1307  if (Child && Visit(Child))
1308  return true;
1309  }
1310  return false;
1311  }
1312  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1313 };
1314 } // namespace
1315 
1319  for (auto &RefExpr : VarList) {
1320  DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
1321  VarDecl *VD = cast<VarDecl>(DE->getDecl());
1322  SourceLocation ILoc = DE->getExprLoc();
1323 
1324  // Mark variable as used.
1325  VD->setReferenced();
1326  VD->markUsed(Context);
1327 
1328  QualType QType = VD->getType();
1329  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1330  // It will be analyzed later.
1331  Vars.push_back(DE);
1332  continue;
1333  }
1334 
1335  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1336  // A threadprivate variable must not have an incomplete type.
1337  if (RequireCompleteType(ILoc, VD->getType(),
1338  diag::err_omp_threadprivate_incomplete_type)) {
1339  continue;
1340  }
1341 
1342  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1343  // A threadprivate variable must not have a reference type.
1344  if (VD->getType()->isReferenceType()) {
1345  Diag(ILoc, diag::err_omp_ref_type_arg)
1346  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1347  bool IsDecl =
1348  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1349  Diag(VD->getLocation(),
1350  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1351  << VD;
1352  continue;
1353  }
1354 
1355  // Check if this is a TLS variable. If TLS is not being supported, produce
1356  // the corresponding diagnostic.
1357  if ((VD->getTLSKind() != VarDecl::TLS_None &&
1358  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1359  getLangOpts().OpenMPUseTLS &&
1361  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1362  !VD->isLocalVarDecl())) {
1363  Diag(ILoc, diag::err_omp_var_thread_local)
1364  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1365  bool IsDecl =
1366  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1367  Diag(VD->getLocation(),
1368  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1369  << VD;
1370  continue;
1371  }
1372 
1373  // Check if initial value of threadprivate variable reference variable with
1374  // local storage (it is not supported by runtime).
1375  if (auto Init = VD->getAnyInitializer()) {
1376  LocalVarRefChecker Checker(*this);
1377  if (Checker.Visit(Init))
1378  continue;
1379  }
1380 
1381  Vars.push_back(RefExpr);
1382  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1383  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1384  Context, SourceRange(Loc, Loc)));
1385  if (auto *ML = Context.getASTMutationListener())
1386  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1387  }
1388  OMPThreadPrivateDecl *D = nullptr;
1389  if (!Vars.empty()) {
1391  Vars);
1392  D->setAccess(AS_public);
1393  }
1394  return D;
1395 }
1396 
1397 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1398  const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1399  bool IsLoopIterVar = false) {
1400  if (DVar.RefExpr) {
1401  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1402  << getOpenMPClauseName(DVar.CKind);
1403  return;
1404  }
1405  enum {
1406  PDSA_StaticMemberShared,
1407  PDSA_StaticLocalVarShared,
1408  PDSA_LoopIterVarPrivate,
1409  PDSA_LoopIterVarLinear,
1410  PDSA_LoopIterVarLastprivate,
1411  PDSA_ConstVarShared,
1412  PDSA_GlobalVarShared,
1413  PDSA_TaskVarFirstprivate,
1414  PDSA_LocalVarPrivate,
1415  PDSA_Implicit
1416  } Reason = PDSA_Implicit;
1417  bool ReportHint = false;
1418  auto ReportLoc = D->getLocation();
1419  auto *VD = dyn_cast<VarDecl>(D);
1420  if (IsLoopIterVar) {
1421  if (DVar.CKind == OMPC_private)
1422  Reason = PDSA_LoopIterVarPrivate;
1423  else if (DVar.CKind == OMPC_lastprivate)
1424  Reason = PDSA_LoopIterVarLastprivate;
1425  else
1426  Reason = PDSA_LoopIterVarLinear;
1427  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1428  DVar.CKind == OMPC_firstprivate) {
1429  Reason = PDSA_TaskVarFirstprivate;
1430  ReportLoc = DVar.ImplicitDSALoc;
1431  } else if (VD && VD->isStaticLocal())
1432  Reason = PDSA_StaticLocalVarShared;
1433  else if (VD && VD->isStaticDataMember())
1434  Reason = PDSA_StaticMemberShared;
1435  else if (VD && VD->isFileVarDecl())
1436  Reason = PDSA_GlobalVarShared;
1437  else if (D->getType().isConstant(SemaRef.getASTContext()))
1438  Reason = PDSA_ConstVarShared;
1439  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1440  ReportHint = true;
1441  Reason = PDSA_LocalVarPrivate;
1442  }
1443  if (Reason != PDSA_Implicit) {
1444  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1445  << Reason << ReportHint
1446  << getOpenMPDirectiveName(Stack->getCurrentDirective());
1447  } else if (DVar.ImplicitDSALoc.isValid()) {
1448  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1449  << getOpenMPClauseName(DVar.CKind);
1450  }
1451 }
1452 
1453 namespace {
1454 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1455  DSAStackTy *Stack;
1456  Sema &SemaRef;
1457  bool ErrorFound;
1458  CapturedStmt *CS;
1459  llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1460  llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1461 
1462 public:
1463  void VisitDeclRefExpr(DeclRefExpr *E) {
1464  if (E->isTypeDependent() || E->isValueDependent() ||
1466  return;
1467  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1468  // Skip internally declared variables.
1469  if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
1470  return;
1471 
1472  auto DVar = Stack->getTopDSA(VD, false);
1473  // Check if the variable has explicit DSA set and stop analysis if it so.
1474  if (DVar.RefExpr) return;
1475 
1476  auto ELoc = E->getExprLoc();
1477  auto DKind = Stack->getCurrentDirective();
1478  // The default(none) clause requires that each variable that is referenced
1479  // in the construct, and does not have a predetermined data-sharing
1480  // attribute, must have its data-sharing attribute explicitly determined
1481  // by being listed in a data-sharing attribute clause.
1482  if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1483  isParallelOrTaskRegion(DKind) &&
1484  VarsWithInheritedDSA.count(VD) == 0) {
1485  VarsWithInheritedDSA[VD] = E;
1486  return;
1487  }
1488 
1489  // OpenMP [2.9.3.6, Restrictions, p.2]
1490  // A list item that appears in a reduction clause of the innermost
1491  // enclosing worksharing or parallel construct may not be accessed in an
1492  // explicit task.
1493  DVar = Stack->hasInnermostDSA(
1494  VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1495  [](OpenMPDirectiveKind K) -> bool {
1496  return isOpenMPParallelDirective(K) ||
1498  },
1499  false);
1500  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
1501  ErrorFound = true;
1502  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1503  ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1504  return;
1505  }
1506 
1507  // Define implicit data-sharing attributes for task.
1508  DVar = Stack->getImplicitDSA(VD, false);
1509  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
1510  !Stack->isLoopControlVariable(VD).first)
1511  ImplicitFirstprivate.push_back(E);
1512  }
1513  }
1514  void VisitMemberExpr(MemberExpr *E) {
1515  if (E->isTypeDependent() || E->isValueDependent() ||
1517  return;
1518  if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
1519  if (auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) {
1520  auto DVar = Stack->getTopDSA(FD, false);
1521  // Check if the variable has explicit DSA set and stop analysis if it
1522  // so.
1523  if (DVar.RefExpr)
1524  return;
1525 
1526  auto ELoc = E->getExprLoc();
1527  auto DKind = Stack->getCurrentDirective();
1528  // OpenMP [2.9.3.6, Restrictions, p.2]
1529  // A list item that appears in a reduction clause of the innermost
1530  // enclosing worksharing or parallel construct may not be accessed in
1531  // an explicit task.
1532  DVar = Stack->hasInnermostDSA(
1533  FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1534  [](OpenMPDirectiveKind K) -> bool {
1535  return isOpenMPParallelDirective(K) ||
1538  },
1539  false);
1540  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
1541  ErrorFound = true;
1542  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1543  ReportOriginalDSA(SemaRef, Stack, FD, DVar);
1544  return;
1545  }
1546 
1547  // Define implicit data-sharing attributes for task.
1548  DVar = Stack->getImplicitDSA(FD, false);
1549  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
1550  !Stack->isLoopControlVariable(FD).first)
1551  ImplicitFirstprivate.push_back(E);
1552  }
1553  }
1554  }
1555  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
1556  for (auto *C : S->clauses()) {
1557  // Skip analysis of arguments of implicitly defined firstprivate clause
1558  // for task directives.
1559  if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid()))
1560  for (auto *CC : C->children()) {
1561  if (CC)
1562  Visit(CC);
1563  }
1564  }
1565  }
1566  void VisitStmt(Stmt *S) {
1567  for (auto *C : S->children()) {
1568  if (C && !isa<OMPExecutableDirective>(C))
1569  Visit(C);
1570  }
1571  }
1572 
1573  bool isErrorFound() { return ErrorFound; }
1574  ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
1575  llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
1576  return VarsWithInheritedDSA;
1577  }
1578 
1579  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
1580  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
1581 };
1582 } // namespace
1583 
1585  switch (DKind) {
1586  case OMPD_parallel:
1587  case OMPD_parallel_for:
1588  case OMPD_parallel_for_simd:
1589  case OMPD_parallel_sections:
1590  case OMPD_teams: {
1591  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1592  QualType KmpInt32PtrTy =
1593  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1594  Sema::CapturedParamNameType Params[] = {
1595  std::make_pair(".global_tid.", KmpInt32PtrTy),
1596  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1597  std::make_pair(StringRef(), QualType()) // __context with shared vars
1598  };
1599  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1600  Params);
1601  break;
1602  }
1603  case OMPD_simd:
1604  case OMPD_for:
1605  case OMPD_for_simd:
1606  case OMPD_sections:
1607  case OMPD_section:
1608  case OMPD_single:
1609  case OMPD_master:
1610  case OMPD_critical:
1611  case OMPD_taskgroup:
1612  case OMPD_distribute:
1613  case OMPD_ordered:
1614  case OMPD_atomic:
1615  case OMPD_target_data:
1616  case OMPD_target:
1617  case OMPD_target_parallel:
1618  case OMPD_target_parallel_for:
1619  case OMPD_target_parallel_for_simd: {
1620  Sema::CapturedParamNameType Params[] = {
1621  std::make_pair(StringRef(), QualType()) // __context with shared vars
1622  };
1623  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1624  Params);
1625  break;
1626  }
1627  case OMPD_task: {
1628  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1631  EPI.Variadic = true;
1632  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
1633  Sema::CapturedParamNameType Params[] = {
1634  std::make_pair(".global_tid.", KmpInt32Ty),
1635  std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
1636  std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
1637  std::make_pair(".copy_fn.",
1638  Context.getPointerType(CopyFnType).withConst()),
1639  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
1640  std::make_pair(StringRef(), QualType()) // __context with shared vars
1641  };
1642  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1643  Params);
1644  // Mark this captured region as inlined, because we don't use outlined
1645  // function directly.
1647  AlwaysInlineAttr::CreateImplicit(
1648  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
1649  break;
1650  }
1651  case OMPD_taskloop:
1652  case OMPD_taskloop_simd: {
1653  QualType KmpInt32Ty =
1654  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
1655  QualType KmpUInt64Ty =
1656  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
1657  QualType KmpInt64Ty =
1658  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
1661  EPI.Variadic = true;
1662  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
1663  Sema::CapturedParamNameType Params[] = {
1664  std::make_pair(".global_tid.", KmpInt32Ty),
1665  std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
1666  std::make_pair(".privates.",
1668  std::make_pair(
1669  ".copy_fn.",
1670  Context.getPointerType(CopyFnType).withConst().withRestrict()),
1671  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
1672  std::make_pair(".lb.", KmpUInt64Ty),
1673  std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty),
1674  std::make_pair(".liter.", KmpInt32Ty),
1675  std::make_pair(StringRef(), QualType()) // __context with shared vars
1676  };
1677  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1678  Params);
1679  // Mark this captured region as inlined, because we don't use outlined
1680  // function directly.
1682  AlwaysInlineAttr::CreateImplicit(
1683  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
1684  break;
1685  }
1686  case OMPD_distribute_parallel_for_simd:
1687  case OMPD_distribute_simd:
1688  case OMPD_distribute_parallel_for: {
1689  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1690  QualType KmpInt32PtrTy =
1691  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
1692  Sema::CapturedParamNameType Params[] = {
1693  std::make_pair(".global_tid.", KmpInt32PtrTy),
1694  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1695  std::make_pair(".previous.lb.", Context.getSizeType()),
1696  std::make_pair(".previous.ub.", Context.getSizeType()),
1697  std::make_pair(StringRef(), QualType()) // __context with shared vars
1698  };
1699  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1700  Params);
1701  break;
1702  }
1703  case OMPD_threadprivate:
1704  case OMPD_taskyield:
1705  case OMPD_barrier:
1706  case OMPD_taskwait:
1707  case OMPD_cancellation_point:
1708  case OMPD_cancel:
1709  case OMPD_flush:
1710  case OMPD_target_enter_data:
1711  case OMPD_target_exit_data:
1712  case OMPD_declare_reduction:
1713  case OMPD_declare_simd:
1714  case OMPD_declare_target:
1715  case OMPD_end_declare_target:
1716  case OMPD_target_update:
1717  llvm_unreachable("OpenMP Directive is not allowed");
1718  case OMPD_unknown:
1719  llvm_unreachable("Unknown OpenMP directive");
1720  }
1721 }
1722 
1724  Expr *CaptureExpr, bool WithInit,
1725  bool AsExpression) {
1726  assert(CaptureExpr);
1727  ASTContext &C = S.getASTContext();
1728  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
1729  QualType Ty = Init->getType();
1730  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
1731  if (S.getLangOpts().CPlusPlus)
1732  Ty = C.getLValueReferenceType(Ty);
1733  else {
1734  Ty = C.getPointerType(Ty);
1735  ExprResult Res =
1736  S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
1737  if (!Res.isUsable())
1738  return nullptr;
1739  Init = Res.get();
1740  }
1741  WithInit = true;
1742  }
1743  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty);
1744  if (!WithInit)
1745  CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
1746  S.CurContext->addHiddenDecl(CED);
1747  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false,
1748  /*TypeMayContainAuto=*/true);
1749  return CED;
1750 }
1751 
1752 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
1753  bool WithInit) {
1754  OMPCapturedExprDecl *CD;
1755  if (auto *VD = S.IsOpenMPCapturedDecl(D))
1756  CD = cast<OMPCapturedExprDecl>(VD);
1757  else
1758  CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
1759  /*AsExpression=*/false);
1760  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
1761  CaptureExpr->getExprLoc());
1762 }
1763 
1764 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
1765  if (!Ref) {
1766  auto *CD =
1767  buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."),
1768  CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true);
1769  Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
1770  CaptureExpr->getExprLoc());
1771  }
1772  ExprResult Res = Ref;
1773  if (!S.getLangOpts().CPlusPlus &&
1774  CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
1775  Ref->getType()->isPointerType())
1776  Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
1777  if (!Res.isUsable())
1778  return ExprError();
1779  return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get());
1780 }
1781 
1783  ArrayRef<OMPClause *> Clauses) {
1784  if (!S.isUsable()) {
1786  return StmtError();
1787  }
1788 
1789  OMPOrderedClause *OC = nullptr;
1790  OMPScheduleClause *SC = nullptr;
1792  // This is required for proper codegen.
1793  for (auto *Clause : Clauses) {
1794  if (isOpenMPPrivate(Clause->getClauseKind()) ||
1795  Clause->getClauseKind() == OMPC_copyprivate ||
1796  (getLangOpts().OpenMPUseTLS &&
1798  Clause->getClauseKind() == OMPC_copyin)) {
1799  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
1800  // Mark all variables in private list clauses as used in inner region.
1801  for (auto *VarRef : Clause->children()) {
1802  if (auto *E = cast_or_null<Expr>(VarRef)) {
1804  }
1805  }
1806  DSAStack->setForceVarCapturing(/*V=*/false);
1807  } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) {
1808  // Mark all variables in private list clauses as used in inner region.
1809  // Required for proper codegen of combined directives.
1810  // TODO: add processing for other clauses.
1811  if (auto *C = OMPClauseWithPreInit::get(Clause)) {
1812  if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
1813  for (auto *D : DS->decls())
1814  MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
1815  }
1816  }
1817  if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
1818  if (auto *E = C->getPostUpdateExpr())
1820  }
1821  }
1822  if (Clause->getClauseKind() == OMPC_schedule)
1823  SC = cast<OMPScheduleClause>(Clause);
1824  else if (Clause->getClauseKind() == OMPC_ordered)
1825  OC = cast<OMPOrderedClause>(Clause);
1826  else if (Clause->getClauseKind() == OMPC_linear)
1827  LCs.push_back(cast<OMPLinearClause>(Clause));
1828  }
1829  bool ErrorFound = false;
1830  // OpenMP, 2.7.1 Loop Construct, Restrictions
1831  // The nonmonotonic modifier cannot be specified if an ordered clause is
1832  // specified.
1833  if (SC &&
1834  (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
1835  SC->getSecondScheduleModifier() ==
1836  OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
1837  OC) {
1838  Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
1841  diag::err_omp_schedule_nonmonotonic_ordered)
1842  << SourceRange(OC->getLocStart(), OC->getLocEnd());
1843  ErrorFound = true;
1844  }
1845  if (!LCs.empty() && OC && OC->getNumForLoops()) {
1846  for (auto *C : LCs) {
1847  Diag(C->getLocStart(), diag::err_omp_linear_ordered)
1848  << SourceRange(OC->getLocStart(), OC->getLocEnd());
1849  }
1850  ErrorFound = true;
1851  }
1852  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
1853  isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
1854  OC->getNumForLoops()) {
1855  Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
1856  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
1857  ErrorFound = true;
1858  }
1859  if (ErrorFound) {
1861  return StmtError();
1862  }
1863  return ActOnCapturedRegionEnd(S.get());
1864 }
1865 
1866 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
1867  OpenMPDirectiveKind CurrentRegion,
1868  const DeclarationNameInfo &CurrentName,
1869  OpenMPDirectiveKind CancelRegion,
1870  SourceLocation StartLoc) {
1871  // Allowed nesting of constructs
1872  // +------------------+-----------------+------------------------------------+
1873  // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)|
1874  // +------------------+-----------------+------------------------------------+
1875  // | parallel | parallel | * |
1876  // | parallel | for | * |
1877  // | parallel | for simd | * |
1878  // | parallel | master | * |
1879  // | parallel | critical | * |
1880  // | parallel | simd | * |
1881  // | parallel | sections | * |
1882  // | parallel | section | + |
1883  // | parallel | single | * |
1884  // | parallel | parallel for | * |
1885  // | parallel |parallel for simd| * |
1886  // | parallel |parallel sections| * |
1887  // | parallel | task | * |
1888  // | parallel | taskyield | * |
1889  // | parallel | barrier | * |
1890  // | parallel | taskwait | * |
1891  // | parallel | taskgroup | * |
1892  // | parallel | flush | * |
1893  // | parallel | ordered | + |
1894  // | parallel | atomic | * |
1895  // | parallel | target | * |
1896  // | parallel | target parallel | * |
1897  // | parallel | target parallel | * |
1898  // | | for | |
1899  // | parallel | target enter | * |
1900  // | | data | |
1901  // | parallel | target exit | * |
1902  // | | data | |
1903  // | parallel | teams | + |
1904  // | parallel | cancellation | |
1905  // | | point | ! |
1906  // | parallel | cancel | ! |
1907  // | parallel | taskloop | * |
1908  // | parallel | taskloop simd | * |
1909  // | parallel | distribute | + |
1910  // | parallel | distribute | + |
1911  // | | parallel for | |
1912  // | parallel | distribute | + |
1913  // | |parallel for simd| |
1914  // | parallel | distribute simd | + |
1915  // +------------------+-----------------+------------------------------------+
1916  // | for | parallel | * |
1917  // | for | for | + |
1918  // | for | for simd | + |
1919  // | for | master | + |
1920  // | for | critical | * |
1921  // | for | simd | * |
1922  // | for | sections | + |
1923  // | for | section | + |
1924  // | for | single | + |
1925  // | for | parallel for | * |
1926  // | for |parallel for simd| * |
1927  // | for |parallel sections| * |
1928  // | for | task | * |
1929  // | for | taskyield | * |
1930  // | for | barrier | + |
1931  // | for | taskwait | * |
1932  // | for | taskgroup | * |
1933  // | for | flush | * |
1934  // | for | ordered | * (if construct is ordered) |
1935  // | for | atomic | * |
1936  // | for | target | * |
1937  // | for | target parallel | * |
1938  // | for | target parallel | * |
1939  // | | for | |
1940  // | for | target enter | * |
1941  // | | data | |
1942  // | for | target exit | * |
1943  // | | data | |
1944  // | for | teams | + |
1945  // | for | cancellation | |
1946  // | | point | ! |
1947  // | for | cancel | ! |
1948  // | for | taskloop | * |
1949  // | for | taskloop simd | * |
1950  // | for | distribute | + |
1951  // | for | distribute | + |
1952  // | | parallel for | |
1953  // | for | distribute | + |
1954  // | |parallel for simd| |
1955  // | for | distribute simd | + |
1956  // | for | target parallel | + |
1957  // | | for simd | |
1958  // +------------------+-----------------+------------------------------------+
1959  // | master | parallel | * |
1960  // | master | for | + |
1961  // | master | for simd | + |
1962  // | master | master | * |
1963  // | master | critical | * |
1964  // | master | simd | * |
1965  // | master | sections | + |
1966  // | master | section | + |
1967  // | master | single | + |
1968  // | master | parallel for | * |
1969  // | master |parallel for simd| * |
1970  // | master |parallel sections| * |
1971  // | master | task | * |
1972  // | master | taskyield | * |
1973  // | master | barrier | + |
1974  // | master | taskwait | * |
1975  // | master | taskgroup | * |
1976  // | master | flush | * |
1977  // | master | ordered | + |
1978  // | master | atomic | * |
1979  // | master | target | * |
1980  // | master | target parallel | * |
1981  // | master | target parallel | * |
1982  // | | for | |
1983  // | master | target enter | * |
1984  // | | data | |
1985  // | master | target exit | * |
1986  // | | data | |
1987  // | master | teams | + |
1988  // | master | cancellation | |
1989  // | | point | |
1990  // | master | cancel | |
1991  // | master | taskloop | * |
1992  // | master | taskloop simd | * |
1993  // | master | distribute | + |
1994  // | master | distribute | + |
1995  // | | parallel for | |
1996  // | master | distribute | + |
1997  // | |parallel for simd| |
1998  // | master | distribute simd | + |
1999  // | master | target parallel | + |
2000  // | | for simd | |
2001  // +------------------+-----------------+------------------------------------+
2002  // | critical | parallel | * |
2003  // | critical | for | + |
2004  // | critical | for simd | + |
2005  // | critical | master | * |
2006  // | critical | critical | * (should have different names) |
2007  // | critical | simd | * |
2008  // | critical | sections | + |
2009  // | critical | section | + |
2010  // | critical | single | + |
2011  // | critical | parallel for | * |
2012  // | critical |parallel for simd| * |
2013  // | critical |parallel sections| * |
2014  // | critical | task | * |
2015  // | critical | taskyield | * |
2016  // | critical | barrier | + |
2017  // | critical | taskwait | * |
2018  // | critical | taskgroup | * |
2019  // | critical | ordered | + |
2020  // | critical | atomic | * |
2021  // | critical | target | * |
2022  // | critical | target parallel | * |
2023  // | critical | target parallel | * |
2024  // | | for | |
2025  // | critical | target enter | * |
2026  // | | data | |
2027  // | critical | target exit | * |
2028  // | | data | |
2029  // | critical | teams | + |
2030  // | critical | cancellation | |
2031  // | | point | |
2032  // | critical | cancel | |
2033  // | critical | taskloop | * |
2034  // | critical | taskloop simd | * |
2035  // | critical | distribute | + |
2036  // | critical | distribute | + |
2037  // | | parallel for | |
2038  // | critical | distribute | + |
2039  // | |parallel for simd| |
2040  // | critical | distribute simd | + |
2041  // | critical | target parallel | + |
2042  // | | for simd | |
2043  // +------------------+-----------------+------------------------------------+
2044  // | simd | parallel | |
2045  // | simd | for | |
2046  // | simd | for simd | |
2047  // | simd | master | |
2048  // | simd | critical | |
2049  // | simd | simd | * |
2050  // | simd | sections | |
2051  // | simd | section | |
2052  // | simd | single | |
2053  // | simd | parallel for | |
2054  // | simd |parallel for simd| |
2055  // | simd |parallel sections| |
2056  // | simd | task | |
2057  // | simd | taskyield | |
2058  // | simd | barrier | |
2059  // | simd | taskwait | |
2060  // | simd | taskgroup | |
2061  // | simd | flush | |
2062  // | simd | ordered | + (with simd clause) |
2063  // | simd | atomic | |
2064  // | simd | target | |
2065  // | simd | target parallel | |
2066  // | simd | target parallel | |
2067  // | | for | |
2068  // | simd | target enter | |
2069  // | | data | |
2070  // | simd | target exit | |
2071  // | | data | |
2072  // | simd | teams | |
2073  // | simd | cancellation | |
2074  // | | point | |
2075  // | simd | cancel | |
2076  // | simd | taskloop | |
2077  // | simd | taskloop simd | |
2078  // | simd | distribute | |
2079  // | simd | distribute | |
2080  // | | parallel for | |
2081  // | simd | distribute | |
2082  // | |parallel for simd| |
2083  // | simd | distribute simd | |
2084  // | simd | target parallel | |
2085  // | | for simd | |
2086  // +------------------+-----------------+------------------------------------+
2087  // | for simd | parallel | |
2088  // | for simd | for | |
2089  // | for simd | for simd | |
2090  // | for simd | master | |
2091  // | for simd | critical | |
2092  // | for simd | simd | * |
2093  // | for simd | sections | |
2094  // | for simd | section | |
2095  // | for simd | single | |
2096  // | for simd | parallel for | |
2097  // | for simd |parallel for simd| |
2098  // | for simd |parallel sections| |
2099  // | for simd | task | |
2100  // | for simd | taskyield | |
2101  // | for simd | barrier | |
2102  // | for simd | taskwait | |
2103  // | for simd | taskgroup | |
2104  // | for simd | flush | |
2105  // | for simd | ordered | + (with simd clause) |
2106  // | for simd | atomic | |
2107  // | for simd | target | |
2108  // | for simd | target parallel | |
2109  // | for simd | target parallel | |
2110  // | | for | |
2111  // | for simd | target enter | |
2112  // | | data | |
2113  // | for simd | target exit | |
2114  // | | data | |
2115  // | for simd | teams | |
2116  // | for simd | cancellation | |
2117  // | | point | |
2118  // | for simd | cancel | |
2119  // | for simd | taskloop | |
2120  // | for simd | taskloop simd | |
2121  // | for simd | distribute | |
2122  // | for simd | distribute | |
2123  // | | parallel for | |
2124  // | for simd | distribute | |
2125  // | |parallel for simd| |
2126  // | for simd | distribute simd | |
2127  // | for simd | target parallel | |
2128  // | | for simd | |
2129  // +------------------+-----------------+------------------------------------+
2130  // | parallel for simd| parallel | |
2131  // | parallel for simd| for | |
2132  // | parallel for simd| for simd | |
2133  // | parallel for simd| master | |
2134  // | parallel for simd| critical | |
2135  // | parallel for simd| simd | * |
2136  // | parallel for simd| sections | |
2137  // | parallel for simd| section | |
2138  // | parallel for simd| single | |
2139  // | parallel for simd| parallel for | |
2140  // | parallel for simd|parallel for simd| |
2141  // | parallel for simd|parallel sections| |
2142  // | parallel for simd| task | |
2143  // | parallel for simd| taskyield | |
2144  // | parallel for simd| barrier | |
2145  // | parallel for simd| taskwait | |
2146  // | parallel for simd| taskgroup | |
2147  // | parallel for simd| flush | |
2148  // | parallel for simd| ordered | + (with simd clause) |
2149  // | parallel for simd| atomic | |
2150  // | parallel for simd| target | |
2151  // | parallel for simd| target parallel | |
2152  // | parallel for simd| target parallel | |
2153  // | | for | |
2154  // | parallel for simd| target enter | |
2155  // | | data | |
2156  // | parallel for simd| target exit | |
2157  // | | data | |
2158  // | parallel for simd| teams | |
2159  // | parallel for simd| cancellation | |
2160  // | | point | |
2161  // | parallel for simd| cancel | |
2162  // | parallel for simd| taskloop | |
2163  // | parallel for simd| taskloop simd | |
2164  // | parallel for simd| distribute | |
2165  // | parallel for simd| distribute | |
2166  // | | parallel for | |
2167  // | parallel for simd| distribute | |
2168  // | |parallel for simd| |
2169  // | parallel for simd| distribute simd | |
2170  // | | for simd | |
2171  // +------------------+-----------------+------------------------------------+
2172  // | sections | parallel | * |
2173  // | sections | for | + |
2174  // | sections | for simd | + |
2175  // | sections | master | + |
2176  // | sections | critical | * |
2177  // | sections | simd | * |
2178  // | sections | sections | + |
2179  // | sections | section | * |
2180  // | sections | single | + |
2181  // | sections | parallel for | * |
2182  // | sections |parallel for simd| * |
2183  // | sections |parallel sections| * |
2184  // | sections | task | * |
2185  // | sections | taskyield | * |
2186  // | sections | barrier | + |
2187  // | sections | taskwait | * |
2188  // | sections | taskgroup | * |
2189  // | sections | flush | * |
2190  // | sections | ordered | + |
2191  // | sections | atomic | * |
2192  // | sections | target | * |
2193  // | sections | target parallel | * |
2194  // | sections | target parallel | * |
2195  // | | for | |
2196  // | sections | target enter | * |
2197  // | | data | |
2198  // | sections | target exit | * |
2199  // | | data | |
2200  // | sections | teams | + |
2201  // | sections | cancellation | |
2202  // | | point | ! |
2203  // | sections | cancel | ! |
2204  // | sections | taskloop | * |
2205  // | sections | taskloop simd | * |
2206  // | sections | distribute | + |
2207  // | sections | distribute | + |
2208  // | | parallel for | |
2209  // | sections | distribute | + |
2210  // | |parallel for simd| |
2211  // | sections | distribute simd | + |
2212  // | sections | target parallel | + |
2213  // | | for simd | |
2214  // +------------------+-----------------+------------------------------------+
2215  // | section | parallel | * |
2216  // | section | for | + |
2217  // | section | for simd | + |
2218  // | section | master | + |
2219  // | section | critical | * |
2220  // | section | simd | * |
2221  // | section | sections | + |
2222  // | section | section | + |
2223  // | section | single | + |
2224  // | section | parallel for | * |
2225  // | section |parallel for simd| * |
2226  // | section |parallel sections| * |
2227  // | section | task | * |
2228  // | section | taskyield | * |
2229  // | section | barrier | + |
2230  // | section | taskwait | * |
2231  // | section | taskgroup | * |
2232  // | section | flush | * |
2233  // | section | ordered | + |
2234  // | section | atomic | * |
2235  // | section | target | * |
2236  // | section | target parallel | * |
2237  // | section | target parallel | * |
2238  // | | for | |
2239  // | section | target enter | * |
2240  // | | data | |
2241  // | section | target exit | * |
2242  // | | data | |
2243  // | section | teams | + |
2244  // | section | cancellation | |
2245  // | | point | ! |
2246  // | section | cancel | ! |
2247  // | section | taskloop | * |
2248  // | section | taskloop simd | * |
2249  // | section | distribute | + |
2250  // | section | distribute | + |
2251  // | | parallel for | |
2252  // | section | distribute | + |
2253  // | |parallel for simd| |
2254  // | section | distribute simd | + |
2255  // | section | target parallel | + |
2256  // | | for simd | |
2257  // +------------------+-----------------+------------------------------------+
2258  // | single | parallel | * |
2259  // | single | for | + |
2260  // | single | for simd | + |
2261  // | single | master | + |
2262  // | single | critical | * |
2263  // | single | simd | * |
2264  // | single | sections | + |
2265  // | single | section | + |
2266  // | single | single | + |
2267  // | single | parallel for | * |
2268  // | single |parallel for simd| * |
2269  // | single |parallel sections| * |
2270  // | single | task | * |
2271  // | single | taskyield | * |
2272  // | single | barrier | + |
2273  // | single | taskwait | * |
2274  // | single | taskgroup | * |
2275  // | single | flush | * |
2276  // | single | ordered | + |
2277  // | single | atomic | * |
2278  // | single | target | * |
2279  // | single | target parallel | * |
2280  // | single | target parallel | * |
2281  // | | for | |
2282  // | single | target enter | * |
2283  // | | data | |
2284  // | single | target exit | * |
2285  // | | data | |
2286  // | single | teams | + |
2287  // | single | cancellation | |
2288  // | | point | |
2289  // | single | cancel | |
2290  // | single | taskloop | * |
2291  // | single | taskloop simd | * |
2292  // | single | distribute | + |
2293  // | single | distribute | + |
2294  // | | parallel for | |
2295  // | single | distribute | + |
2296  // | |parallel for simd| |
2297  // | single | distribute simd | + |
2298  // | single | target parallel | + |
2299  // | | for simd | |
2300  // +------------------+-----------------+------------------------------------+
2301  // | parallel for | parallel | * |
2302  // | parallel for | for | + |
2303  // | parallel for | for simd | + |
2304  // | parallel for | master | + |
2305  // | parallel for | critical | * |
2306  // | parallel for | simd | * |
2307  // | parallel for | sections | + |
2308  // | parallel for | section | + |
2309  // | parallel for | single | + |
2310  // | parallel for | parallel for | * |
2311  // | parallel for |parallel for simd| * |
2312  // | parallel for |parallel sections| * |
2313  // | parallel for | task | * |
2314  // | parallel for | taskyield | * |
2315  // | parallel for | barrier | + |
2316  // | parallel for | taskwait | * |
2317  // | parallel for | taskgroup | * |
2318  // | parallel for | flush | * |
2319  // | parallel for | ordered | * (if construct is ordered) |
2320  // | parallel for | atomic | * |
2321  // | parallel for | target | * |
2322  // | parallel for | target parallel | * |
2323  // | parallel for | target parallel | * |
2324  // | | for | |
2325  // | parallel for | target enter | * |
2326  // | | data | |
2327  // | parallel for | target exit | * |
2328  // | | data | |
2329  // | parallel for | teams | + |
2330  // | parallel for | cancellation | |
2331  // | | point | ! |
2332  // | parallel for | cancel | ! |
2333  // | parallel for | taskloop | * |
2334  // | parallel for | taskloop simd | * |
2335  // | parallel for | distribute | + |
2336  // | parallel for | distribute | + |
2337  // | | parallel for | |
2338  // | parallel for | distribute | + |
2339  // | |parallel for simd| |
2340  // | parallel for | distribute simd | + |
2341  // | parallel for | target parallel | + |
2342  // | | for simd | |
2343  // +------------------+-----------------+------------------------------------+
2344  // | parallel sections| parallel | * |
2345  // | parallel sections| for | + |
2346  // | parallel sections| for simd | + |
2347  // | parallel sections| master | + |
2348  // | parallel sections| critical | + |
2349  // | parallel sections| simd | * |
2350  // | parallel sections| sections | + |
2351  // | parallel sections| section | * |
2352  // | parallel sections| single | + |
2353  // | parallel sections| parallel for | * |
2354  // | parallel sections|parallel for simd| * |
2355  // | parallel sections|parallel sections| * |
2356  // | parallel sections| task | * |
2357  // | parallel sections| taskyield | * |
2358  // | parallel sections| barrier | + |
2359  // | parallel sections| taskwait | * |
2360  // | parallel sections| taskgroup | * |
2361  // | parallel sections| flush | * |
2362  // | parallel sections| ordered | + |
2363  // | parallel sections| atomic | * |
2364  // | parallel sections| target | * |
2365  // | parallel sections| target parallel | * |
2366  // | parallel sections| target parallel | * |
2367  // | | for | |
2368  // | parallel sections| target enter | * |
2369  // | | data | |
2370  // | parallel sections| target exit | * |
2371  // | | data | |
2372  // | parallel sections| teams | + |
2373  // | parallel sections| cancellation | |
2374  // | | point | ! |
2375  // | parallel sections| cancel | ! |
2376  // | parallel sections| taskloop | * |
2377  // | parallel sections| taskloop simd | * |
2378  // | parallel sections| distribute | + |
2379  // | parallel sections| distribute | + |
2380  // | | parallel for | |
2381  // | parallel sections| distribute | + |
2382  // | |parallel for simd| |
2383  // | parallel sections| distribute simd | + |
2384  // | parallel sections| target parallel | + |
2385  // | | for simd | |
2386  // +------------------+-----------------+------------------------------------+
2387  // | task | parallel | * |
2388  // | task | for | + |
2389  // | task | for simd | + |
2390  // | task | master | + |
2391  // | task | critical | * |
2392  // | task | simd | * |
2393  // | task | sections | + |
2394  // | task | section | + |
2395  // | task | single | + |
2396  // | task | parallel for | * |
2397  // | task |parallel for simd| * |
2398  // | task |parallel sections| * |
2399  // | task | task | * |
2400  // | task | taskyield | * |
2401  // | task | barrier | + |
2402  // | task | taskwait | * |
2403  // | task | taskgroup | * |
2404  // | task | flush | * |
2405  // | task | ordered | + |
2406  // | task | atomic | * |
2407  // | task | target | * |
2408  // | task | target parallel | * |
2409  // | task | target parallel | * |
2410  // | | for | |
2411  // | task | target enter | * |
2412  // | | data | |
2413  // | task | target exit | * |
2414  // | | data | |
2415  // | task | teams | + |
2416  // | task | cancellation | |
2417  // | | point | ! |
2418  // | task | cancel | ! |
2419  // | task | taskloop | * |
2420  // | task | taskloop simd | * |
2421  // | task | distribute | + |
2422  // | task | distribute | + |
2423  // | | parallel for | |
2424  // | task | distribute | + |
2425  // | |parallel for simd| |
2426  // | task | distribute simd | + |
2427  // | task | target parallel | + |
2428  // | | for simd | |
2429  // +------------------+-----------------+------------------------------------+
2430  // | ordered | parallel | * |
2431  // | ordered | for | + |
2432  // | ordered | for simd | + |
2433  // | ordered | master | * |
2434  // | ordered | critical | * |
2435  // | ordered | simd | * |
2436  // | ordered | sections | + |
2437  // | ordered | section | + |
2438  // | ordered | single | + |
2439  // | ordered | parallel for | * |
2440  // | ordered |parallel for simd| * |
2441  // | ordered |parallel sections| * |
2442  // | ordered | task | * |
2443  // | ordered | taskyield | * |
2444  // | ordered | barrier | + |
2445  // | ordered | taskwait | * |
2446  // | ordered | taskgroup | * |
2447  // | ordered | flush | * |
2448  // | ordered | ordered | + |
2449  // | ordered | atomic | * |
2450  // | ordered | target | * |
2451  // | ordered | target parallel | * |
2452  // | ordered | target parallel | * |
2453  // | | for | |
2454  // | ordered | target enter | * |
2455  // | | data | |
2456  // | ordered | target exit | * |
2457  // | | data | |
2458  // | ordered | teams | + |
2459  // | ordered | cancellation | |
2460  // | | point | |
2461  // | ordered | cancel | |
2462  // | ordered | taskloop | * |
2463  // | ordered | taskloop simd | * |
2464  // | ordered | distribute | + |
2465  // | ordered | distribute | + |
2466  // | | parallel for | |
2467  // | ordered | distribute | + |
2468  // | |parallel for simd| |
2469  // | ordered | distribute simd | + |
2470  // | ordered | target parallel | + |
2471  // | | for simd | |
2472  // +------------------+-----------------+------------------------------------+
2473  // | atomic | parallel | |
2474  // | atomic | for | |
2475  // | atomic | for simd | |
2476  // | atomic | master | |
2477  // | atomic | critical | |
2478  // | atomic | simd | |
2479  // | atomic | sections | |
2480  // | atomic | section | |
2481  // | atomic | single | |
2482  // | atomic | parallel for | |
2483  // | atomic |parallel for simd| |
2484  // | atomic |parallel sections| |
2485  // | atomic | task | |
2486  // | atomic | taskyield | |
2487  // | atomic | barrier | |
2488  // | atomic | taskwait | |
2489  // | atomic | taskgroup | |
2490  // | atomic | flush | |
2491  // | atomic | ordered | |
2492  // | atomic | atomic | |
2493  // | atomic | target | |
2494  // | atomic | target parallel | |
2495  // | atomic | target parallel | |
2496  // | | for | |
2497  // | atomic | target enter | |
2498  // | | data | |
2499  // | atomic | target exit | |
2500  // | | data | |
2501  // | atomic | teams | |
2502  // | atomic | cancellation | |
2503  // | | point | |
2504  // | atomic | cancel | |
2505  // | atomic | taskloop | |
2506  // | atomic | taskloop simd | |
2507  // | atomic | distribute | |
2508  // | atomic | distribute | |
2509  // | | parallel for | |
2510  // | atomic | distribute | |
2511  // | |parallel for simd| |
2512  // | atomic | distribute simd | |
2513  // | atomic | target parallel | |
2514  // | | for simd | |
2515  // +------------------+-----------------+------------------------------------+
2516  // | target | parallel | * |
2517  // | target | for | * |
2518  // | target | for simd | * |
2519  // | target | master | * |
2520  // | target | critical | * |
2521  // | target | simd | * |
2522  // | target | sections | * |
2523  // | target | section | * |
2524  // | target | single | * |
2525  // | target | parallel for | * |
2526  // | target |parallel for simd| * |
2527  // | target |parallel sections| * |
2528  // | target | task | * |
2529  // | target | taskyield | * |
2530  // | target | barrier | * |
2531  // | target | taskwait | * |
2532  // | target | taskgroup | * |
2533  // | target | flush | * |
2534  // | target | ordered | * |
2535  // | target | atomic | * |
2536  // | target | target | |
2537  // | target | target parallel | |
2538  // | target | target parallel | |
2539  // | | for | |
2540  // | target | target enter | |
2541  // | | data | |
2542  // | target | target exit | |
2543  // | | data | |
2544  // | target | teams | * |
2545  // | target | cancellation | |
2546  // | | point | |
2547  // | target | cancel | |
2548  // | target | taskloop | * |
2549  // | target | taskloop simd | * |
2550  // | target | distribute | + |
2551  // | target | distribute | + |
2552  // | | parallel for | |
2553  // | target | distribute | + |
2554  // | |parallel for simd| |
2555  // | target | distribute simd | + |
2556  // | target | target parallel | |
2557  // | | for simd | |
2558  // +------------------+-----------------+------------------------------------+
2559  // | target parallel | parallel | * |
2560  // | target parallel | for | * |
2561  // | target parallel | for simd | * |
2562  // | target parallel | master | * |
2563  // | target parallel | critical | * |
2564  // | target parallel | simd | * |
2565  // | target parallel | sections | * |
2566  // | target parallel | section | * |
2567  // | target parallel | single | * |
2568  // | target parallel | parallel for | * |
2569  // | target parallel |parallel for simd| * |
2570  // | target parallel |parallel sections| * |
2571  // | target parallel | task | * |
2572  // | target parallel | taskyield | * |
2573  // | target parallel | barrier | * |
2574  // | target parallel | taskwait | * |
2575  // | target parallel | taskgroup | * |
2576  // | target parallel | flush | * |
2577  // | target parallel | ordered | * |
2578  // | target parallel | atomic | * |
2579  // | target parallel | target | |
2580  // | target parallel | target parallel | |
2581  // | target parallel | target parallel | |
2582  // | | for | |
2583  // | target parallel | target enter | |
2584  // | | data | |
2585  // | target parallel | target exit | |
2586  // | | data | |
2587  // | target parallel | teams | |
2588  // | target parallel | cancellation | |
2589  // | | point | ! |
2590  // | target parallel | cancel | ! |
2591  // | target parallel | taskloop | * |
2592  // | target parallel | taskloop simd | * |
2593  // | target parallel | distribute | |
2594  // | target parallel | distribute | |
2595  // | | parallel for | |
2596  // | target parallel | distribute | |
2597  // | |parallel for simd| |
2598  // | target parallel | distribute simd | |
2599  // | target parallel | target parallel | |
2600  // | | for simd | |
2601  // +------------------+-----------------+------------------------------------+
2602  // | target parallel | parallel | * |
2603  // | for | | |
2604  // | target parallel | for | * |
2605  // | for | | |
2606  // | target parallel | for simd | * |
2607  // | for | | |
2608  // | target parallel | master | * |
2609  // | for | | |
2610  // | target parallel | critical | * |
2611  // | for | | |
2612  // | target parallel | simd | * |
2613  // | for | | |
2614  // | target parallel | sections | * |
2615  // | for | | |
2616  // | target parallel | section | * |
2617  // | for | | |
2618  // | target parallel | single | * |
2619  // | for | | |
2620  // | target parallel | parallel for | * |
2621  // | for | | |
2622  // | target parallel |parallel for simd| * |
2623  // | for | | |
2624  // | target parallel |parallel sections| * |
2625  // | for | | |
2626  // | target parallel | task | * |
2627  // | for | | |
2628  // | target parallel | taskyield | * |
2629  // | for | | |
2630  // | target parallel | barrier | * |
2631  // | for | | |
2632  // | target parallel | taskwait | * |
2633  // | for | | |
2634  // | target parallel | taskgroup | * |
2635  // | for | | |
2636  // | target parallel | flush | * |
2637  // | for | | |
2638  // | target parallel | ordered | * |
2639  // | for | | |
2640  // | target parallel | atomic | * |
2641  // | for | | |
2642  // | target parallel | target | |
2643  // | for | | |
2644  // | target parallel | target parallel | |
2645  // | for | | |
2646  // | target parallel | target parallel | |
2647  // | for | for | |
2648  // | target parallel | target enter | |
2649  // | for | data | |
2650  // | target parallel | target exit | |
2651  // | for | data | |
2652  // | target parallel | teams | |
2653  // | for | | |
2654  // | target parallel | cancellation | |
2655  // | for | point | ! |
2656  // | target parallel | cancel | ! |
2657  // | for | | |
2658  // | target parallel | taskloop | * |
2659  // | for | | |
2660  // | target parallel | taskloop simd | * |
2661  // | for | | |
2662  // | target parallel | distribute | |
2663  // | for | | |
2664  // | target parallel | distribute | |
2665  // | for | parallel for | |
2666  // | target parallel | distribute | |
2667  // | for |parallel for simd| |
2668  // | target parallel | distribute simd | |
2669  // | for | | |
2670  // | target parallel | target parallel | |
2671  // | for | for simd | |
2672  // +------------------+-----------------+------------------------------------+
2673  // | teams | parallel | * |
2674  // | teams | for | + |
2675  // | teams | for simd | + |
2676  // | teams | master | + |
2677  // | teams | critical | + |
2678  // | teams | simd | + |
2679  // | teams | sections | + |
2680  // | teams | section | + |
2681  // | teams | single | + |
2682  // | teams | parallel for | * |
2683  // | teams |parallel for simd| * |
2684  // | teams |parallel sections| * |
2685  // | teams | task | + |
2686  // | teams | taskyield | + |
2687  // | teams | barrier | + |
2688  // | teams | taskwait | + |
2689  // | teams | taskgroup | + |
2690  // | teams | flush | + |
2691  // | teams | ordered | + |
2692  // | teams | atomic | + |
2693  // | teams | target | + |
2694  // | teams | target parallel | + |
2695  // | teams | target parallel | + |
2696  // | | for | |
2697  // | teams | target enter | + |
2698  // | | data | |
2699  // | teams | target exit | + |
2700  // | | data | |
2701  // | teams | teams | + |
2702  // | teams | cancellation | |
2703  // | | point | |
2704  // | teams | cancel | |
2705  // | teams | taskloop | + |
2706  // | teams | taskloop simd | + |
2707  // | teams | distribute | ! |
2708  // | teams | distribute | ! |
2709  // | | parallel for | |
2710  // | teams | distribute | ! |
2711  // | |parallel for simd| |
2712  // | teams | distribute simd | ! |
2713  // | teams | target parallel | + |
2714  // | | for simd | |
2715  // +------------------+-----------------+------------------------------------+
2716  // | taskloop | parallel | * |
2717  // | taskloop | for | + |
2718  // | taskloop | for simd | + |
2719  // | taskloop | master | + |
2720  // | taskloop | critical | * |
2721  // | taskloop | simd | * |
2722  // | taskloop | sections | + |
2723  // | taskloop | section | + |
2724  // | taskloop | single | + |
2725  // | taskloop | parallel for | * |
2726  // | taskloop |parallel for simd| * |
2727  // | taskloop |parallel sections| * |
2728  // | taskloop | task | * |
2729  // | taskloop | taskyield | * |
2730  // | taskloop | barrier | + |
2731  // | taskloop | taskwait | * |
2732  // | taskloop | taskgroup | * |
2733  // | taskloop | flush | * |
2734  // | taskloop | ordered | + |
2735  // | taskloop | atomic | * |
2736  // | taskloop | target | * |
2737  // | taskloop | target parallel | * |
2738  // | taskloop | target parallel | * |
2739  // | | for | |
2740  // | taskloop | target enter | * |
2741  // | | data | |
2742  // | taskloop | target exit | * |
2743  // | | data | |
2744  // | taskloop | teams | + |
2745  // | taskloop | cancellation | |
2746  // | | point | |
2747  // | taskloop | cancel | |
2748  // | taskloop | taskloop | * |
2749  // | taskloop | distribute | + |
2750  // | taskloop | distribute | + |
2751  // | | parallel for | |
2752  // | taskloop | distribute | + |
2753  // | |parallel for simd| |
2754  // | taskloop | distribute simd | + |
2755  // | taskloop | target parallel | * |
2756  // | | for simd | |
2757  // +------------------+-----------------+------------------------------------+
2758  // | taskloop simd | parallel | |
2759  // | taskloop simd | for | |
2760  // | taskloop simd | for simd | |
2761  // | taskloop simd | master | |
2762  // | taskloop simd | critical | |
2763  // | taskloop simd | simd | * |
2764  // | taskloop simd | sections | |
2765  // | taskloop simd | section | |
2766  // | taskloop simd | single | |
2767  // | taskloop simd | parallel for | |
2768  // | taskloop simd |parallel for simd| |
2769  // | taskloop simd |parallel sections| |
2770  // | taskloop simd | task | |
2771  // | taskloop simd | taskyield | |
2772  // | taskloop simd | barrier | |
2773  // | taskloop simd | taskwait | |
2774  // | taskloop simd | taskgroup | |
2775  // | taskloop simd | flush | |
2776  // | taskloop simd | ordered | + (with simd clause) |
2777  // | taskloop simd | atomic | |
2778  // | taskloop simd | target | |
2779  // | taskloop simd | target parallel | |
2780  // | taskloop simd | target parallel | |
2781  // | | for | |
2782  // | taskloop simd | target enter | |
2783  // | | data | |
2784  // | taskloop simd | target exit | |
2785  // | | data | |
2786  // | taskloop simd | teams | |
2787  // | taskloop simd | cancellation | |
2788  // | | point | |
2789  // | taskloop simd | cancel | |
2790  // | taskloop simd | taskloop | |
2791  // | taskloop simd | taskloop simd | |
2792  // | taskloop simd | distribute | |
2793  // | taskloop simd | distribute | |
2794  // | | parallel for | |
2795  // | taskloop simd | distribute | |
2796  // | |parallel for simd| |
2797  // | taskloop simd | distribute simd | |
2798  // | taskloop simd | target parallel | |
2799  // | | for simd | |
2800  // +------------------+-----------------+------------------------------------+
2801  // | distribute | parallel | * |
2802  // | distribute | for | * |
2803  // | distribute | for simd | * |
2804  // | distribute | master | * |
2805  // | distribute | critical | * |
2806  // | distribute | simd | * |
2807  // | distribute | sections | * |
2808  // | distribute | section | * |
2809  // | distribute | single | * |
2810  // | distribute | parallel for | * |
2811  // | distribute |parallel for simd| * |
2812  // | distribute |parallel sections| * |
2813  // | distribute | task | * |
2814  // | distribute | taskyield | * |
2815  // | distribute | barrier | * |
2816  // | distribute | taskwait | * |
2817  // | distribute | taskgroup | * |
2818  // | distribute | flush | * |
2819  // | distribute | ordered | + |
2820  // | distribute | atomic | * |
2821  // | distribute | target | |
2822  // | distribute | target parallel | |
2823  // | distribute | target parallel | |
2824  // | | for | |
2825  // | distribute | target enter | |
2826  // | | data | |
2827  // | distribute | target exit | |
2828  // | | data | |
2829  // | distribute | teams | |
2830  // | distribute | cancellation | + |
2831  // | | point | |
2832  // | distribute | cancel | + |
2833  // | distribute | taskloop | * |
2834  // | distribute | taskloop simd | * |
2835  // | distribute | distribute | |
2836  // | distribute | distribute | |
2837  // | | parallel for | |
2838  // | distribute | distribute | |
2839  // | |parallel for simd| |
2840  // | distribute | distribute simd | |
2841  // | distribute | target parallel | |
2842  // | | for simd | |
2843  // +------------------+-----------------+------------------------------------+
2844  // | distribute | parallel | * |
2845  // | parallel for | | |
2846  // | distribute | for | * |
2847  // | parallel for | | |
2848  // | distribute | for simd | * |
2849  // | parallel for | | |
2850  // | distribute | master | * |
2851  // | parallel for | | |
2852  // | distribute | critical | * |
2853  // | parallel for | | |
2854  // | distribute | simd | * |
2855  // | parallel for | | |
2856  // | distribute | sections | * |
2857  // | parallel for | | |
2858  // | distribute | section | * |
2859  // | parallel for | | |
2860  // | distribute | single | * |
2861  // | parallel for | | |
2862  // | distribute | parallel for | * |
2863  // | parallel for | | |
2864  // | distribute |parallel for simd| * |
2865  // | parallel for | | |
2866  // | distribute |parallel sections| * |
2867  // | parallel for | | |
2868  // | distribute | task | * |
2869  // | parallel for | | |
2870  // | parallel for | | |
2871  // | distribute | taskyield | * |
2872  // | parallel for | | |
2873  // | distribute | barrier | * |
2874  // | parallel for | | |
2875  // | distribute | taskwait | * |
2876  // | parallel for | | |
2877  // | distribute | taskgroup | * |
2878  // | parallel for | | |
2879  // | distribute | flush | * |
2880  // | parallel for | | |
2881  // | distribute | ordered | + |
2882  // | parallel for | | |
2883  // | distribute | atomic | * |
2884  // | parallel for | | |
2885  // | distribute | target | |
2886  // | parallel for | | |
2887  // | distribute | target parallel | |
2888  // | parallel for | | |
2889  // | distribute | target parallel | |
2890  // | parallel for | for | |
2891  // | distribute | target enter | |
2892  // | parallel for | data | |
2893  // | distribute | target exit | |
2894  // | parallel for | data | |
2895  // | distribute | teams | |
2896  // | parallel for | | |
2897  // | distribute | cancellation | + |
2898  // | parallel for | point | |
2899  // | distribute | cancel | + |
2900  // | parallel for | | |
2901  // | distribute | taskloop | * |
2902  // | parallel for | | |
2903  // | distribute | taskloop simd | * |
2904  // | parallel for | | |
2905  // | distribute | distribute | |
2906  // | parallel for | | |
2907  // | distribute | distribute | |
2908  // | parallel for | parallel for | |
2909  // | distribute | distribute | |
2910  // | parallel for |parallel for simd| |
2911  // | distribute | distribute simd | |
2912  // | parallel for | | |
2913  // | distribute | target parallel | |
2914  // | parallel for | for simd | |
2915  // +------------------+-----------------+------------------------------------+
2916  // | distribute | parallel | * |
2917  // | parallel for simd| | |
2918  // | distribute | for | * |
2919  // | parallel for simd| | |
2920  // | distribute | for simd | * |
2921  // | parallel for simd| | |
2922  // | distribute | master | * |
2923  // | parallel for simd| | |
2924  // | distribute | critical | * |
2925  // | parallel for simd| | |
2926  // | distribute | simd | * |
2927  // | parallel for simd| | |
2928  // | distribute | sections | * |
2929  // | parallel for simd| | |
2930  // | distribute | section | * |
2931  // | parallel for simd| | |
2932  // | distribute | single | * |
2933  // | parallel for simd| | |
2934  // | distribute | parallel for | * |
2935  // | parallel for simd| | |
2936  // | distribute |parallel for simd| * |
2937  // | parallel for simd| | |
2938  // | distribute |parallel sections| * |
2939  // | parallel for simd| | |
2940  // | distribute | task | * |
2941  // | parallel for simd| | |
2942  // | distribute | taskyield | * |
2943  // | parallel for simd| | |
2944  // | distribute | barrier | * |
2945  // | parallel for simd| | |
2946  // | distribute | taskwait | * |
2947  // | parallel for simd| | |
2948  // | distribute | taskgroup | * |
2949  // | parallel for simd| | |
2950  // | distribute | flush | * |
2951  // | parallel for simd| | |
2952  // | distribute | ordered | + |
2953  // | parallel for simd| | |
2954  // | distribute | atomic | * |
2955  // | parallel for simd| | |
2956  // | distribute | target | |
2957  // | parallel for simd| | |
2958  // | distribute | target parallel | |
2959  // | parallel for simd| | |
2960  // | distribute | target parallel | |
2961  // | parallel for simd| for | |
2962  // | distribute | target enter | |
2963  // | parallel for simd| data | |
2964  // | distribute | target exit | |
2965  // | parallel for simd| data | |
2966  // | distribute | teams | |
2967  // | parallel for simd| | |
2968  // | distribute | cancellation | + |
2969  // | parallel for simd| point | |
2970  // | distribute | cancel | + |
2971  // | parallel for simd| | |
2972  // | distribute | taskloop | * |
2973  // | parallel for simd| | |
2974  // | distribute | taskloop simd | * |
2975  // | parallel for simd| | |
2976  // | distribute | distribute | |
2977  // | parallel for simd| | |
2978  // | distribute | distribute | * |
2979  // | parallel for simd| parallel for | |
2980  // | distribute | distribute | * |
2981  // | parallel for simd|parallel for simd| |
2982  // | distribute | distribute simd | * |
2983  // | parallel for simd| | |
2984  // | distribute | target parallel | |
2985  // | parallel for simd| for simd | |
2986  // +------------------+-----------------+------------------------------------+
2987  // | distribute simd | parallel | * |
2988  // | distribute simd | for | * |
2989  // | distribute simd | for simd | * |
2990  // | distribute simd | master | * |
2991  // | distribute simd | critical | * |
2992  // | distribute simd | simd | * |
2993  // | distribute simd | sections | * |
2994  // | distribute simd | section | * |
2995  // | distribute simd | single | * |
2996  // | distribute simd | parallel for | * |
2997  // | distribute simd |parallel for simd| * |
2998  // | distribute simd |parallel sections| * |
2999  // | distribute simd | task | * |
3000  // | distribute simd | taskyield | * |
3001  // | distribute simd | barrier | * |
3002  // | distribute simd | taskwait | * |
3003  // | distribute simd | taskgroup | * |
3004  // | distribute simd | flush | * |
3005  // | distribute simd | ordered | + |
3006  // | distribute simd | atomic | * |
3007  // | distribute simd | target | * |
3008  // | distribute simd | target parallel | * |
3009  // | distribute simd | target parallel | * |
3010  // | | for | |
3011  // | distribute simd | target enter | * |
3012  // | | data | |
3013  // | distribute simd | target exit | * |
3014  // | | data | |
3015  // | distribute simd | teams | * |
3016  // | distribute simd | cancellation | + |
3017  // | | point | |
3018  // | distribute simd | cancel | + |
3019  // | distribute simd | taskloop | * |
3020  // | distribute simd | taskloop simd | * |
3021  // | distribute simd | distribute | |
3022  // | distribute simd | distribute | * |
3023  // | | parallel for | |
3024  // | distribute simd | distribute | * |
3025  // | |parallel for simd| |
3026  // | distribute simd | distribute simd | * |
3027  // | distribute simd | target parallel | * |
3028  // | | for simd | |
3029  // +------------------+-----------------+------------------------------------+
3030  // | target parallel | parallel | * |
3031  // | for simd | | |
3032  // | target parallel | for | * |
3033  // | for simd | | |
3034  // | target parallel | for simd | * |
3035  // | for simd | | |
3036  // | target parallel | master | * |
3037  // | for simd | | |
3038  // | target parallel | critical | * |
3039  // | for simd | | |
3040  // | target parallel | simd | ! |
3041  // | for simd | | |
3042  // | target parallel | sections | * |
3043  // | for simd | | |
3044  // | target parallel | section | * |
3045  // | for simd | | |
3046  // | target parallel | single | * |
3047  // | for simd | | |
3048  // | target parallel | parallel for | * |
3049  // | for simd | | |
3050  // | target parallel |parallel for simd| * |
3051  // | for simd | | |
3052  // | target parallel |parallel sections| * |
3053  // | for simd | | |
3054  // | target parallel | task | * |
3055  // | for simd | | |
3056  // | target parallel | taskyield | * |
3057  // | for simd | | |
3058  // | target parallel | barrier | * |
3059  // | for simd | | |
3060  // | target parallel | taskwait | * |
3061  // | for simd | | |
3062  // | target parallel | taskgroup | * |
3063  // | for simd | | |
3064  // | target parallel | flush | * |
3065  // | for simd | | |
3066  // | target parallel | ordered | + (with simd clause) |
3067  // | for simd | | |
3068  // | target parallel | atomic | * |
3069  // | for simd | | |
3070  // | target parallel | target | * |
3071  // | for simd | | |
3072  // | target parallel | target parallel | * |
3073  // | for simd | | |
3074  // | target parallel | target parallel | * |
3075  // | for simd | for | |
3076  // | target parallel | target enter | * |
3077  // | for simd | data | |
3078  // | target parallel | target exit | * |
3079  // | for simd | data | |
3080  // | target parallel | teams | * |
3081  // | for simd | | |
3082  // | target parallel | cancellation | * |
3083  // | for simd | point | |
3084  // | target parallel | cancel | * |
3085  // | for simd | | |
3086  // | target parallel | taskloop | * |
3087  // | for simd | | |
3088  // | target parallel | taskloop simd | * |
3089  // | for simd | | |
3090  // | target parallel | distribute | * |
3091  // | for simd | | |
3092  // | target parallel | distribute | * |
3093  // | for simd | parallel for | |
3094  // | target parallel | distribute | * |
3095  // | for simd |parallel for simd| |
3096  // | target parallel | distribute simd | * |
3097  // | for simd | | |
3098  // | target parallel | target parallel | * |
3099  // | for simd | for simd | |
3100  // +------------------+-----------------+------------------------------------+
3101  if (Stack->getCurScope()) {
3102  auto ParentRegion = Stack->getParentDirective();
3103  auto OffendingRegion = ParentRegion;
3104  bool NestingProhibited = false;
3105  bool CloseNesting = true;
3106  enum {
3107  NoRecommend,
3108  ShouldBeInParallelRegion,
3109  ShouldBeInOrderedRegion,
3110  ShouldBeInTargetRegion,
3111  ShouldBeInTeamsRegion
3112  } Recommend = NoRecommend;
3113  if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
3114  // OpenMP [2.16, Nesting of Regions]
3115  // OpenMP constructs may not be nested inside a simd region.
3116  // OpenMP [2.8.1,simd Construct, Restrictions]
3117  // An ordered construct with the simd clause is the only OpenMP
3118  // construct that can appear in the simd region.
3119  // Allowing a SIMD consruct nested in another SIMD construct is an
3120  // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
3121  // message.
3122  SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
3123  ? diag::err_omp_prohibited_region_simd
3124  : diag::warn_omp_nesting_simd);
3125  return CurrentRegion != OMPD_simd;
3126  }
3127  if (ParentRegion == OMPD_atomic) {
3128  // OpenMP [2.16, Nesting of Regions]
3129  // OpenMP constructs may not be nested inside an atomic region.
3130  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3131  return true;
3132  }
3133  if (CurrentRegion == OMPD_section) {
3134  // OpenMP [2.7.2, sections Construct, Restrictions]
3135  // Orphaned section directives are prohibited. That is, the section
3136  // directives must appear within the sections construct and must not be
3137  // encountered elsewhere in the sections region.
3138  if (ParentRegion != OMPD_sections &&
3139  ParentRegion != OMPD_parallel_sections) {
3140  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3141  << (ParentRegion != OMPD_unknown)
3142  << getOpenMPDirectiveName(ParentRegion);
3143  return true;
3144  }
3145  return false;
3146  }
3147  // Allow some constructs to be orphaned (they could be used in functions,
3148  // called from OpenMP regions with the required preconditions).
3149  if (ParentRegion == OMPD_unknown)
3150  return false;
3151  if (CurrentRegion == OMPD_cancellation_point ||
3152  CurrentRegion == OMPD_cancel) {
3153  // OpenMP [2.16, Nesting of Regions]
3154  // A cancellation point construct for which construct-type-clause is
3155  // taskgroup must be nested inside a task construct. A cancellation
3156  // point construct for which construct-type-clause is not taskgroup must
3157  // be closely nested inside an OpenMP construct that matches the type
3158  // specified in construct-type-clause.
3159  // A cancel construct for which construct-type-clause is taskgroup must be
3160  // nested inside a task construct. A cancel construct for which
3161  // construct-type-clause is not taskgroup must be closely nested inside an
3162  // OpenMP construct that matches the type specified in
3163  // construct-type-clause.
3164  NestingProhibited =
3165  !((CancelRegion == OMPD_parallel &&
3166  (ParentRegion == OMPD_parallel ||
3167  ParentRegion == OMPD_target_parallel)) ||
3168  (CancelRegion == OMPD_for &&
3169  (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
3170  ParentRegion == OMPD_target_parallel_for)) ||
3171  (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3172  (CancelRegion == OMPD_sections &&
3173  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3174  ParentRegion == OMPD_parallel_sections)));
3175  } else if (CurrentRegion == OMPD_master) {
3176  // OpenMP [2.16, Nesting of Regions]
3177  // A master region may not be closely nested inside a worksharing,
3178  // atomic, or explicit task region.
3179  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3180  isOpenMPTaskingDirective(ParentRegion);
3181  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
3182  // OpenMP [2.16, Nesting of Regions]
3183  // A critical region may not be nested (closely or otherwise) inside a
3184  // critical region with the same name. Note that this restriction is not
3185  // sufficient to prevent deadlock.
3186  SourceLocation PreviousCriticalLoc;
3187  bool DeadLock =
3188  Stack->hasDirective([CurrentName, &PreviousCriticalLoc](
3190  const DeclarationNameInfo &DNI,
3191  SourceLocation Loc)
3192  ->bool {
3193  if (K == OMPD_critical &&
3194  DNI.getName() == CurrentName.getName()) {
3195  PreviousCriticalLoc = Loc;
3196  return true;
3197  } else
3198  return false;
3199  },
3200  false /* skip top directive */);
3201  if (DeadLock) {
3202  SemaRef.Diag(StartLoc,
3203  diag::err_omp_prohibited_region_critical_same_name)
3204  << CurrentName.getName();
3205  if (PreviousCriticalLoc.isValid())
3206  SemaRef.Diag(PreviousCriticalLoc,
3207  diag::note_omp_previous_critical_region);
3208  return true;
3209  }
3210  } else if (CurrentRegion == OMPD_barrier) {
3211  // OpenMP [2.16, Nesting of Regions]
3212  // A barrier region may not be closely nested inside a worksharing,
3213  // explicit task, critical, ordered, atomic, or master region.
3214  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3215  isOpenMPTaskingDirective(ParentRegion) ||
3216  ParentRegion == OMPD_master ||
3217  ParentRegion == OMPD_critical ||
3218  ParentRegion == OMPD_ordered;
3219  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
3220  !isOpenMPParallelDirective(CurrentRegion)) {
3221  // OpenMP [2.16, Nesting of Regions]
3222  // A worksharing region may not be closely nested inside a worksharing,
3223  // explicit task, critical, ordered, atomic, or master region.
3224  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3225  isOpenMPTaskingDirective(ParentRegion) ||
3226  ParentRegion == OMPD_master ||
3227  ParentRegion == OMPD_critical ||
3228  ParentRegion == OMPD_ordered;
3229  Recommend = ShouldBeInParallelRegion;
3230  } else if (CurrentRegion == OMPD_ordered) {
3231  // OpenMP [2.16, Nesting of Regions]
3232  // An ordered region may not be closely nested inside a critical,
3233  // atomic, or explicit task region.
3234  // An ordered region must be closely nested inside a loop region (or
3235  // parallel loop region) with an ordered clause.
3236  // OpenMP [2.8.1,simd Construct, Restrictions]
3237  // An ordered construct with the simd clause is the only OpenMP construct
3238  // that can appear in the simd region.
3239  NestingProhibited = ParentRegion == OMPD_critical ||
3240  isOpenMPTaskingDirective(ParentRegion) ||
3241  !(isOpenMPSimdDirective(ParentRegion) ||
3242  Stack->isParentOrderedRegion());
3243  Recommend = ShouldBeInOrderedRegion;
3244  } else if (isOpenMPTeamsDirective(CurrentRegion)) {
3245  // OpenMP [2.16, Nesting of Regions]
3246  // If specified, a teams construct must be contained within a target
3247  // construct.
3248  NestingProhibited = ParentRegion != OMPD_target;
3249  Recommend = ShouldBeInTargetRegion;
3250  Stack->setParentTeamsRegionLoc(Stack->getConstructLoc());
3251  }
3252  if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) {
3253  // OpenMP [2.16, Nesting of Regions]
3254  // distribute, parallel, parallel sections, parallel workshare, and the
3255  // parallel loop and parallel loop SIMD constructs are the only OpenMP
3256  // constructs that can be closely nested in the teams region.
3257  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
3258  !isOpenMPDistributeDirective(CurrentRegion);
3259  Recommend = ShouldBeInParallelRegion;
3260  }
3261  if (!NestingProhibited && isOpenMPDistributeDirective(CurrentRegion)) {
3262  // OpenMP 4.5 [2.17 Nesting of Regions]
3263  // The region associated with the distribute construct must be strictly
3264  // nested inside a teams region
3265  NestingProhibited = !isOpenMPTeamsDirective(ParentRegion);
3266  Recommend = ShouldBeInTeamsRegion;
3267  }
3268  if (!NestingProhibited &&
3269  (isOpenMPTargetExecutionDirective(CurrentRegion) ||
3270  isOpenMPTargetDataManagementDirective(CurrentRegion))) {
3271  // OpenMP 4.5 [2.17 Nesting of Regions]
3272  // If a target, target update, target data, target enter data, or
3273  // target exit data construct is encountered during execution of a
3274  // target region, the behavior is unspecified.
3275  NestingProhibited = Stack->hasDirective(
3276  [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
3277  SourceLocation) -> bool {
3279  OffendingRegion = K;
3280  return true;
3281  } else
3282  return false;
3283  },
3284  false /* don't skip top directive */);
3285  CloseNesting = false;
3286  }
3287  if (NestingProhibited) {
3288  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
3289  << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
3290  << Recommend << getOpenMPDirectiveName(CurrentRegion);
3291  return true;
3292  }
3293  }
3294  return false;
3295 }
3296 
3298  ArrayRef<OMPClause *> Clauses,
3299  ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
3300  bool ErrorFound = false;
3301  unsigned NamedModifiersNumber = 0;
3303  OMPD_unknown + 1);
3304  SmallVector<SourceLocation, 4> NameModifierLoc;
3305  for (const auto *C : Clauses) {
3306  if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
3307  // At most one if clause without a directive-name-modifier can appear on
3308  // the directive.
3309  OpenMPDirectiveKind CurNM = IC->getNameModifier();
3310  if (FoundNameModifiers[CurNM]) {
3311  S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
3312  << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
3313  << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
3314  ErrorFound = true;
3315  } else if (CurNM != OMPD_unknown) {
3316  NameModifierLoc.push_back(IC->getNameModifierLoc());
3317  ++NamedModifiersNumber;
3318  }
3319  FoundNameModifiers[CurNM] = IC;
3320  if (CurNM == OMPD_unknown)
3321  continue;
3322  // Check if the specified name modifier is allowed for the current
3323  // directive.
3324  // At most one if clause with the particular directive-name-modifier can
3325  // appear on the directive.
3326  bool MatchFound = false;
3327  for (auto NM : AllowedNameModifiers) {
3328  if (CurNM == NM) {
3329  MatchFound = true;
3330  break;
3331  }
3332  }
3333  if (!MatchFound) {
3334  S.Diag(IC->getNameModifierLoc(),
3335  diag::err_omp_wrong_if_directive_name_modifier)
3337  ErrorFound = true;
3338  }
3339  }
3340  }
3341  // If any if clause on the directive includes a directive-name-modifier then
3342  // all if clauses on the directive must include a directive-name-modifier.
3343  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
3344  if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3345  S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
3346  diag::err_omp_no_more_if_clause);
3347  } else {
3348  std::string Values;
3349  std::string Sep(", ");
3350  unsigned AllowedCnt = 0;
3351  unsigned TotalAllowedNum =
3352  AllowedNameModifiers.size() - NamedModifiersNumber;
3353  for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
3354  ++Cnt) {
3355  OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
3356  if (!FoundNameModifiers[NM]) {
3357  Values += "'";
3358  Values += getOpenMPDirectiveName(NM);
3359  Values += "'";
3360  if (AllowedCnt + 2 == TotalAllowedNum)
3361  Values += " or ";
3362  else if (AllowedCnt + 1 != TotalAllowedNum)
3363  Values += Sep;
3364  ++AllowedCnt;
3365  }
3366  }
3367  S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
3368  diag::err_omp_unnamed_if_clause)
3369  << (TotalAllowedNum > 1) << Values;
3370  }
3371  for (auto Loc : NameModifierLoc) {
3372  S.Diag(Loc, diag::note_omp_previous_named_if_clause);
3373  }
3374  ErrorFound = true;
3375  }
3376  return ErrorFound;
3377 }
3378 
3381  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
3382  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
3383  StmtResult Res = StmtError();
3384  if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
3385  StartLoc))
3386  return StmtError();
3387 
3388  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
3389  llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
3390  bool ErrorFound = false;
3391  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3392  if (AStmt) {
3393  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
3394 
3395  // Check default data sharing attributes for referenced variables.
3396  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
3397  DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
3398  if (DSAChecker.isErrorFound())
3399  return StmtError();
3400  // Generate list of implicitly defined firstprivate variables.
3401  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3402 
3403  if (!DSAChecker.getImplicitFirstprivate().empty()) {
3404  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
3405  DSAChecker.getImplicitFirstprivate(), SourceLocation(),
3407  ClausesWithImplicit.push_back(Implicit);
3408  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3409  DSAChecker.getImplicitFirstprivate().size();
3410  } else
3411  ErrorFound = true;
3412  }
3413  }
3414 
3415  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
3416  switch (Kind) {
3417  case OMPD_parallel:
3418  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3419  EndLoc);
3420  AllowedNameModifiers.push_back(OMPD_parallel);
3421  break;
3422  case OMPD_simd:
3423  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3424  VarsWithInheritedDSA);
3425  break;
3426  case OMPD_for:
3427  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3428  VarsWithInheritedDSA);
3429  break;
3430  case OMPD_for_simd:
3431  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3432  EndLoc, VarsWithInheritedDSA);
3433  break;
3434  case OMPD_sections:
3435  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3436  EndLoc);
3437  break;
3438  case OMPD_section:
3439  assert(ClausesWithImplicit.empty() &&
3440  "No clauses are allowed for 'omp section' directive");
3441  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3442  break;
3443  case OMPD_single:
3444  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3445  EndLoc);
3446  break;
3447  case OMPD_master:
3448  assert(ClausesWithImplicit.empty() &&
3449  "No clauses are allowed for 'omp master' directive");
3450  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3451  break;
3452  case OMPD_critical:
3453  Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3454  StartLoc, EndLoc);
3455  break;
3456  case OMPD_parallel_for:
3457  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3458  EndLoc, VarsWithInheritedDSA);
3459  AllowedNameModifiers.push_back(OMPD_parallel);
3460  break;
3461  case OMPD_parallel_for_simd:
3463  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3464  AllowedNameModifiers.push_back(OMPD_parallel);
3465  break;
3466  case OMPD_parallel_sections:
3467  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3468  StartLoc, EndLoc);
3469  AllowedNameModifiers.push_back(OMPD_parallel);
3470  break;
3471  case OMPD_task:
3472  Res =
3473  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3474  AllowedNameModifiers.push_back(OMPD_task);
3475  break;
3476  case OMPD_taskyield:
3477  assert(ClausesWithImplicit.empty() &&
3478  "No clauses are allowed for 'omp taskyield' directive");
3479  assert(AStmt == nullptr &&
3480  "No associated statement allowed for 'omp taskyield' directive");
3481  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
3482  break;
3483  case OMPD_barrier:
3484  assert(ClausesWithImplicit.empty() &&
3485  "No clauses are allowed for 'omp barrier' directive");
3486  assert(AStmt == nullptr &&
3487  "No associated statement allowed for 'omp barrier' directive");
3488  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
3489  break;
3490  case OMPD_taskwait:
3491  assert(ClausesWithImplicit.empty() &&
3492  "No clauses are allowed for 'omp taskwait' directive");
3493  assert(AStmt == nullptr &&
3494  "No associated statement allowed for 'omp taskwait' directive");
3495  Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
3496  break;
3497  case OMPD_taskgroup:
3498  assert(ClausesWithImplicit.empty() &&
3499  "No clauses are allowed for 'omp taskgroup' directive");
3500  Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc);
3501  break;
3502  case OMPD_flush:
3503  assert(AStmt == nullptr &&
3504  "No associated statement allowed for 'omp flush' directive");
3505  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3506  break;
3507  case OMPD_ordered:
3508  Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3509  EndLoc);
3510  break;
3511  case OMPD_atomic:
3512  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3513  EndLoc);
3514  break;
3515  case OMPD_teams:
3516  Res =
3517  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3518  break;
3519  case OMPD_target:
3520  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3521  EndLoc);
3522  AllowedNameModifiers.push_back(OMPD_target);
3523  break;
3524  case OMPD_target_parallel:
3525  Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3526  StartLoc, EndLoc);
3527  AllowedNameModifiers.push_back(OMPD_target);
3528  AllowedNameModifiers.push_back(OMPD_parallel);
3529  break;
3530  case OMPD_target_parallel_for:
3532  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3533  AllowedNameModifiers.push_back(OMPD_target);
3534  AllowedNameModifiers.push_back(OMPD_parallel);
3535  break;
3536  case OMPD_cancellation_point:
3537  assert(ClausesWithImplicit.empty() &&
3538  "No clauses are allowed for 'omp cancellation point' directive");
3539  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3540  "cancellation point' directive");
3541  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3542  break;
3543  case OMPD_cancel:
3544  assert(AStmt == nullptr &&
3545  "No associated statement allowed for 'omp cancel' directive");
3546  Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3547  CancelRegion);
3548  AllowedNameModifiers.push_back(OMPD_cancel);
3549  break;
3550  case OMPD_target_data:
3551  Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3552  EndLoc);
3553  AllowedNameModifiers.push_back(OMPD_target_data);
3554  break;
3555  case OMPD_target_enter_data:
3556  Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3557  EndLoc);
3558  AllowedNameModifiers.push_back(OMPD_target_enter_data);
3559  break;
3560  case OMPD_target_exit_data:
3561  Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3562  EndLoc);
3563  AllowedNameModifiers.push_back(OMPD_target_exit_data);
3564  break;
3565  case OMPD_taskloop:
3566  Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3567  EndLoc, VarsWithInheritedDSA);
3568  AllowedNameModifiers.push_back(OMPD_taskloop);
3569  break;
3570  case OMPD_taskloop_simd:
3571  Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3572  EndLoc, VarsWithInheritedDSA);
3573  AllowedNameModifiers.push_back(OMPD_taskloop);
3574  break;
3575  case OMPD_distribute:
3576  Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3577  EndLoc, VarsWithInheritedDSA);
3578  break;
3579  case OMPD_target_update:
3580  assert(!AStmt && "Statement is not allowed for target update");
3581  Res =
3582  ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, EndLoc);
3583  AllowedNameModifiers.push_back(OMPD_target_update);
3584  break;
3585  case OMPD_distribute_parallel_for:
3587  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3588  AllowedNameModifiers.push_back(OMPD_parallel);
3589  break;
3590  case OMPD_distribute_parallel_for_simd:
3592  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3593  AllowedNameModifiers.push_back(OMPD_parallel);
3594  break;
3595  case OMPD_distribute_simd:
3597  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3598  break;
3599  case OMPD_target_parallel_for_simd:
3601  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3602  AllowedNameModifiers.push_back(OMPD_target);
3603  AllowedNameModifiers.push_back(OMPD_parallel);
3604  break;
3605  case OMPD_declare_target:
3606  case OMPD_end_declare_target:
3607  case OMPD_threadprivate:
3608  case OMPD_declare_reduction:
3609  case OMPD_declare_simd:
3610  llvm_unreachable("OpenMP Directive is not allowed");
3611  case OMPD_unknown:
3612  llvm_unreachable("Unknown OpenMP directive");
3613  }
3614 
3615  for (auto P : VarsWithInheritedDSA) {
3616  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3617  << P.first << P.second->getSourceRange();
3618  }
3619  ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3620 
3621  if (!AllowedNameModifiers.empty())
3622  ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3623  ErrorFound;
3624 
3625  if (ErrorFound)
3626  return StmtError();
3627  return Res;
3628 }
3629 
3631  DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3632  ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3633  ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3634  ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3635  assert(Aligneds.size() == Alignments.size());
3636  assert(Linears.size() == LinModifiers.size());
3637  assert(Linears.size() == Steps.size());
3638  if (!DG || DG.get().isNull())
3639  return DeclGroupPtrTy();
3640 
3641  if (!DG.get().isSingleDecl()) {
3642  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3643  return DG;
3644  }
3645  auto *ADecl = DG.get().getSingleDecl();
3646  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3647  ADecl = FTD->getTemplatedDecl();
3648 
3649  auto *FD = dyn_cast<FunctionDecl>(ADecl);
3650  if (!FD) {
3651  Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3652  return DeclGroupPtrTy();
3653  }
3654 
3655  // OpenMP [2.8.2, declare simd construct, Description]
3656  // The parameter of the simdlen clause must be a constant positive integer
3657  // expression.
3658  ExprResult SL;
3659  if (Simdlen)
3660  SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3661  // OpenMP [2.8.2, declare simd construct, Description]
3662  // The special this pointer can be used as if was one of the arguments to the
3663  // function in any of the linear, aligned, or uniform clauses.
3664  // The uniform clause declares one or more arguments to have an invariant
3665  // value for all concurrent invocations of the function in the execution of a
3666  // single SIMD loop.
3667  llvm::DenseMap<Decl *, Expr *> UniformedArgs;
3668  Expr *UniformedLinearThis = nullptr;
3669  for (auto *E : Uniforms) {
3670  E = E->IgnoreParenImpCasts();
3671  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3672  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3673  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3674  FD->getParamDecl(PVD->getFunctionScopeIndex())
3675  ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3676  UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E));
3677  continue;
3678  }
3679  if (isa<CXXThisExpr>(E)) {
3680  UniformedLinearThis = E;
3681  continue;
3682  }
3683  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3684  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3685  }
3686  // OpenMP [2.8.2, declare simd construct, Description]
3687  // The aligned clause declares that the object to which each list item points
3688  // is aligned to the number of bytes expressed in the optional parameter of
3689  // the aligned clause.
3690  // The special this pointer can be used as if was one of the arguments to the
3691  // function in any of the linear, aligned, or uniform clauses.
3692  // The type of list items appearing in the aligned clause must be array,
3693  // pointer, reference to array, or reference to pointer.
3694  llvm::DenseMap<Decl *, Expr *> AlignedArgs;
3695  Expr *AlignedThis = nullptr;
3696  for (auto *E : Aligneds) {
3697  E = E->IgnoreParenImpCasts();
3698  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3699  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3700  auto *CanonPVD = PVD->getCanonicalDecl();
3701  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3702  FD->getParamDecl(PVD->getFunctionScopeIndex())
3703  ->getCanonicalDecl() == CanonPVD) {
3704  // OpenMP [2.8.1, simd construct, Restrictions]
3705  // A list-item cannot appear in more than one aligned clause.
3706  if (AlignedArgs.count(CanonPVD) > 0) {
3707  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3708  << 1 << E->getSourceRange();
3709  Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3710  diag::note_omp_explicit_dsa)
3711  << getOpenMPClauseName(OMPC_aligned);
3712  continue;
3713  }
3714  AlignedArgs[CanonPVD] = E;
3715  QualType QTy = PVD->getType()
3716  .getNonReferenceType()
3717  .getUnqualifiedType()
3718  .getCanonicalType();
3719  const Type *Ty = QTy.getTypePtrOrNull();
3720  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3721  Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3722  << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3723  Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3724  }
3725  continue;
3726  }
3727  }
3728  if (isa<CXXThisExpr>(E)) {
3729  if (AlignedThis) {
3730  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3731  << 2 << E->getSourceRange();
3732  Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3733  << getOpenMPClauseName(OMPC_aligned);
3734  }
3735  AlignedThis = E;
3736  continue;
3737  }
3738  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3739  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3740  }
3741  // The optional parameter of the aligned clause, alignment, must be a constant
3742  // positive integer expression. If no optional parameter is specified,
3743  // implementation-defined default alignments for SIMD instructions on the
3744  // target platforms are assumed.
3745  SmallVector<Expr *, 4> NewAligns;
3746  for (auto *E : Alignments) {
3747  ExprResult Align;
3748  if (E)
3749  Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3750  NewAligns.push_back(Align.get());
3751  }
3752  // OpenMP [2.8.2, declare simd construct, Description]
3753  // The linear clause declares one or more list items to be private to a SIMD
3754  // lane and to have a linear relationship with respect to the iteration space
3755  // of a loop.
3756  // The special this pointer can be used as if was one of the arguments to the
3757  // function in any of the linear, aligned, or uniform clauses.
3758  // When a linear-step expression is specified in a linear clause it must be
3759  // either a constant integer expression or an integer-typed parameter that is
3760  // specified in a uniform clause on the directive.
3761  llvm::DenseMap<Decl *, Expr *> LinearArgs;
3762  const bool IsUniformedThis = UniformedLinearThis != nullptr;
3763  auto MI = LinModifiers.begin();
3764  for (auto *E : Linears) {
3765  auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3766  ++MI;
3767  E = E->IgnoreParenImpCasts();
3768  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3769  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3770  auto *CanonPVD = PVD->getCanonicalDecl();
3771  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3772  FD->getParamDecl(PVD->getFunctionScopeIndex())
3773  ->getCanonicalDecl() == CanonPVD) {
3774  // OpenMP [2.15.3.7, linear Clause, Restrictions]
3775  // A list-item cannot appear in more than one linear clause.
3776  if (LinearArgs.count(CanonPVD) > 0) {
3777  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3778  << getOpenMPClauseName(OMPC_linear)
3779  << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3780  Diag(LinearArgs[CanonPVD]->getExprLoc(),
3781  diag::note_omp_explicit_dsa)
3782  << getOpenMPClauseName(OMPC_linear);
3783  continue;
3784  }
3785  // Each argument can appear in at most one uniform or linear clause.
3786  if (UniformedArgs.count(CanonPVD) > 0) {
3787  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3788  << getOpenMPClauseName(OMPC_linear)
3789  << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
3790  Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3791  diag::note_omp_explicit_dsa)
3793  continue;
3794  }
3795  LinearArgs[CanonPVD] = E;
3796  if (E->isValueDependent() || E->isTypeDependent() ||
3797  E->isInstantiationDependent() ||
3799  continue;
3800  (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3801  PVD->getOriginalType());
3802  continue;
3803  }
3804  }
3805  if (isa<CXXThisExpr>(E)) {
3806  if (UniformedLinearThis) {
3807  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3808  << getOpenMPClauseName(OMPC_linear)
3809  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3810  << E->getSourceRange();
3811  Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3812  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3813  : OMPC_linear);
3814  continue;
3815  }
3816  UniformedLinearThis = E;
3817  if (E->isValueDependent() || E->isTypeDependent() ||
3819  continue;
3820  (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3821  E->getType());
3822  continue;
3823  }
3824  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3825  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3826  }
3827  Expr *Step = nullptr;
3828  Expr *NewStep = nullptr;
3829  SmallVector<Expr *, 4> NewSteps;
3830  for (auto *E : Steps) {
3831  // Skip the same step expression, it was checked already.
3832  if (Step == E || !E) {
3833  NewSteps.push_back(E ? NewStep : nullptr);
3834  continue;
3835  }
3836  Step = E;
3837  if (auto *DRE = dyn_cast<DeclRefExpr>(Step))
3838  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3839  auto *CanonPVD = PVD->getCanonicalDecl();
3840  if (UniformedArgs.count(CanonPVD) == 0) {
3841  Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3842  << Step->getSourceRange();
3843  } else if (E->isValueDependent() || E->isTypeDependent() ||
3844  E->isInstantiationDependent() ||
3846  CanonPVD->getType()->hasIntegerRepresentation())
3847  NewSteps.push_back(Step);
3848  else {
3849  Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3850  << Step->getSourceRange();
3851  }
3852  continue;
3853  }
3854  NewStep = Step;
3855  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3856  !Step->isInstantiationDependent() &&
3859  .get();
3860  if (NewStep)
3861  NewStep = VerifyIntegerConstantExpression(NewStep).get();
3862  }
3863  NewSteps.push_back(NewStep);
3864  }
3865  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3866  Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3867  Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3868  const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3869  const_cast<Expr **>(Linears.data()), Linears.size(),
3870  const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3871  NewSteps.data(), NewSteps.size(), SR);
3872  ADecl->addAttr(NewAttr);
3873  return ConvertDeclToDeclGroup(ADecl);
3874 }
3875 
3877  Stmt *AStmt,
3878  SourceLocation StartLoc,
3879  SourceLocation EndLoc) {
3880  if (!AStmt)
3881  return StmtError();
3882 
3883  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3884  // 1.2.2 OpenMP Language Terminology
3885  // Structured block - An executable statement with a single entry at the
3886  // top and a single exit at the bottom.
3887  // The point of exit cannot be a branch out of the structured block.
3888  // longjmp() and throw() must not violate the entry/exit criteria.
3889  CS->getCapturedDecl()->setNothrow();
3890 
3892 
3893  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3894  DSAStack->isCancelRegion());
3895 }
3896 
3897 namespace {
3898 /// \brief Helper class for checking canonical form of the OpenMP loops and
3899 /// extracting iteration space of each loop in the loop nest, that will be used
3900 /// for IR generation.
3901 class OpenMPIterationSpaceChecker {
3902  /// \brief Reference to Sema.
3903  Sema &SemaRef;
3904  /// \brief A location for diagnostics (when there is no some better location).
3905  SourceLocation DefaultLoc;
3906  /// \brief A location for diagnostics (when increment is not compatible).
3907  SourceLocation ConditionLoc;
3908  /// \brief A source location for referring to loop init later.
3909  SourceRange InitSrcRange;
3910  /// \brief A source location for referring to condition later.
3911  SourceRange ConditionSrcRange;
3912  /// \brief A source location for referring to increment later.
3913  SourceRange IncrementSrcRange;
3914  /// \brief Loop variable.
3915  ValueDecl *LCDecl = nullptr;
3916  /// \brief Reference to loop variable.
3917  Expr *LCRef = nullptr;
3918  /// \brief Lower bound (initializer for the var).
3919  Expr *LB = nullptr;
3920  /// \brief Upper bound.
3921  Expr *UB = nullptr;
3922  /// \brief Loop step (increment).
3923  Expr *Step = nullptr;
3924  /// \brief This flag is true when condition is one of:
3925  /// Var < UB
3926  /// Var <= UB
3927  /// UB > Var
3928  /// UB >= Var
3929  bool TestIsLessOp = false;
3930  /// \brief This flag is true when condition is strict ( < or > ).
3931  bool TestIsStrictOp = false;
3932  /// \brief This flag is true when step is subtracted on each iteration.
3933  bool SubtractStep = false;
3934 
3935 public:
3936  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3937  : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3938  /// \brief Check init-expr for canonical loop form and save loop counter
3939  /// variable - #Var and its initialization value - #LB.
3940  bool CheckInit(Stmt *S, bool EmitDiags = true);
3941  /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
3942  /// for less/greater and for strict/non-strict comparison.
3943  bool CheckCond(Expr *S);
3944  /// \brief Check incr-expr for canonical loop form and return true if it
3945  /// does not conform, otherwise save loop step (#Step).
3946  bool CheckInc(Expr *S);
3947  /// \brief Return the loop counter variable.
3948  ValueDecl *GetLoopDecl() const { return LCDecl; }
3949  /// \brief Return the reference expression to loop counter variable.
3950  Expr *GetLoopDeclRefExpr() const { return LCRef; }
3951  /// \brief Source range of the loop init.
3952  SourceRange GetInitSrcRange() const { return InitSrcRange; }
3953  /// \brief Source range of the loop condition.
3954  SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
3955  /// \brief Source range of the loop increment.
3956  SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
3957  /// \brief True if the step should be subtracted.
3958  bool ShouldSubtractStep() const { return SubtractStep; }
3959  /// \brief Build the expression to calculate the number of iterations.
3960  Expr *
3961  BuildNumIterations(Scope *S, const bool LimitedType,
3962  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3963  /// \brief Build the precondition expression for the loops.
3964  Expr *BuildPreCond(Scope *S, Expr *Cond,
3965  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3966  /// \brief Build reference expression to the counter be used for codegen.
3967  DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3968  DSAStackTy &DSA) const;
3969  /// \brief Build reference expression to the private counter be used for
3970  /// codegen.
3971  Expr *BuildPrivateCounterVar() const;
3972  /// \brief Build initization of the counter be used for codegen.
3973  Expr *BuildCounterInit() const;
3974  /// \brief Build step of the counter be used for codegen.
3975  Expr *BuildCounterStep() const;
3976  /// \brief Return true if any expression is dependent.
3977  bool Dependent() const;
3978 
3979 private:
3980  /// \brief Check the right-hand side of an assignment in the increment
3981  /// expression.
3982  bool CheckIncRHS(Expr *RHS);
3983  /// \brief Helper to set loop counter variable and its initializer.
3984  bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3985  /// \brief Helper to set upper bound.
3986  bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3987  SourceLocation SL);
3988  /// \brief Helper to set loop increment.
3989  bool SetStep(Expr *NewStep, bool Subtract);
3990 };
3991 
3992 bool OpenMPIterationSpaceChecker::Dependent() const {
3993  if (!LCDecl) {
3994  assert(!LB && !UB && !Step);
3995  return false;
3996  }
3997  return LCDecl->getType()->isDependentType() ||
3998  (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3999  (Step && Step->isValueDependent());
4000 }
4001 
4002 static Expr *getExprAsWritten(Expr *E) {
4003  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
4004  E = ExprTemp->getSubExpr();
4005 
4006  if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
4007  E = MTE->GetTemporaryExpr();
4008 
4009  while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
4010  E = Binder->getSubExpr();
4011 
4012  if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
4013  E = ICE->getSubExprAsWritten();
4014  return E->IgnoreParens();
4015 }
4016 
4017 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl,
4018  Expr *NewLCRefExpr,
4019  Expr *NewLB) {
4020  // State consistency checking to ensure correct usage.
4021  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
4022  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
4023  if (!NewLCDecl || !NewLB)
4024  return true;
4025  LCDecl = getCanonicalDecl(NewLCDecl);
4026  LCRef = NewLCRefExpr;
4027  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
4028  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
4029  if ((Ctor->isCopyOrMoveConstructor() ||
4030  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4031  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
4032  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
4033  LB = NewLB;
4034  return false;
4035 }
4036 
4037 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
4038  SourceRange SR, SourceLocation SL) {
4039  // State consistency checking to ensure correct usage.
4040  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
4041  Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
4042  if (!NewUB)
4043  return true;
4044  UB = NewUB;
4045  TestIsLessOp = LessOp;
4046  TestIsStrictOp = StrictOp;
4047  ConditionSrcRange = SR;
4048  ConditionLoc = SL;
4049  return false;
4050 }
4051 
4052 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
4053  // State consistency checking to ensure correct usage.
4054  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
4055  if (!NewStep)
4056  return true;
4057  if (!NewStep->isValueDependent()) {
4058  // Check that the step is integer expression.
4059  SourceLocation StepLoc = NewStep->getLocStart();
4060  ExprResult Val =
4061  SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
4062  if (Val.isInvalid())
4063  return true;
4064  NewStep = Val.get();
4065 
4066  // OpenMP [2.6, Canonical Loop Form, Restrictions]
4067  // If test-expr is of form var relational-op b and relational-op is < or
4068  // <= then incr-expr must cause var to increase on each iteration of the
4069  // loop. If test-expr is of form var relational-op b and relational-op is
4070  // > or >= then incr-expr must cause var to decrease on each iteration of
4071  // the loop.
4072  // If test-expr is of form b relational-op var and relational-op is < or
4073  // <= then incr-expr must cause var to decrease on each iteration of the
4074  // loop. If test-expr is of form b relational-op var and relational-op is
4075  // > or >= then incr-expr must cause var to increase on each iteration of
4076  // the loop.
4077  llvm::APSInt Result;
4078  bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
4079  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
4080  bool IsConstNeg =
4081  IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
4082  bool IsConstPos =
4083  IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
4084  bool IsConstZero = IsConstant && !Result.getBoolValue();
4085  if (UB && (IsConstZero ||
4086  (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
4087  : (IsConstPos || (IsUnsigned && !Subtract))))) {
4088  SemaRef.Diag(NewStep->getExprLoc(),
4089  diag::err_omp_loop_incr_not_compatible)
4090  << LCDecl << TestIsLessOp << NewStep->getSourceRange();
4091  SemaRef.Diag(ConditionLoc,
4092  diag::note_omp_loop_cond_requres_compatible_incr)
4093  << TestIsLessOp << ConditionSrcRange;
4094  return true;
4095  }
4096  if (TestIsLessOp == Subtract) {
4097  NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus,
4098  NewStep).get();
4099  Subtract = !Subtract;
4100  }
4101  }
4102 
4103  Step = NewStep;
4104  SubtractStep = Subtract;
4105  return false;
4106 }
4107 
4108 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
4109  // Check init-expr for canonical loop form and save loop counter
4110  // variable - #Var and its initialization value - #LB.
4111  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
4112  // var = lb
4113  // integer-type var = lb
4114  // random-access-iterator-type var = lb
4115  // pointer-type var = lb
4116  //
4117  if (!S) {
4118  if (EmitDiags) {
4119  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
4120  }
4121  return true;
4122  }
4123  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4124  if (!ExprTemp->cleanupsHaveSideEffects())
4125  S = ExprTemp->getSubExpr();
4126 
4127  InitSrcRange = S->getSourceRange();
4128  if (Expr *E = dyn_cast<Expr>(S))
4129  S = E->IgnoreParens();
4130  if (auto BO = dyn_cast<BinaryOperator>(S)) {
4131  if (BO->getOpcode() == BO_Assign) {
4132  auto *LHS = BO->getLHS()->IgnoreParens();
4133  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4134  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4135  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4136  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4137  return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
4138  }
4139  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4140  if (ME->isArrow() &&
4141  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4142  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4143  }
4144  }
4145  } else if (auto DS = dyn_cast<DeclStmt>(S)) {
4146  if (DS->isSingleDecl()) {
4147  if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
4148  if (Var->hasInit() && !Var->getType()->isReferenceType()) {
4149  // Accept non-canonical init form here but emit ext. warning.
4150  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
4151  SemaRef.Diag(S->getLocStart(),
4152  diag::ext_omp_loop_not_canonical_init)
4153  << S->getSourceRange();
4154  return SetLCDeclAndLB(Var, nullptr, Var->getInit());
4155  }
4156  }
4157  }
4158  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4159  if (CE->getOperator() == OO_Equal) {
4160  auto *LHS = CE->getArg(0);
4161  if (auto DRE = dyn_cast<DeclRefExpr>(LHS)) {
4162  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4163  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4164  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4165  return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
4166  }
4167  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4168  if (ME->isArrow() &&
4169  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4170  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4171  }
4172  }
4173  }
4174 
4175  if (Dependent() || SemaRef.CurContext->isDependentContext())
4176  return false;
4177  if (EmitDiags) {
4178  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
4179  << S->getSourceRange();
4180  }
4181  return true;
4182 }
4183 
4184 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
4185 /// variable (which may be the loop variable) if possible.
4186 static const ValueDecl *GetInitLCDecl(Expr *E) {
4187  if (!E)
4188  return nullptr;
4189  E = getExprAsWritten(E);
4190  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
4191  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
4192  if ((Ctor->isCopyOrMoveConstructor() ||
4193  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4194  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
4195  E = CE->getArg(0)->IgnoreParenImpCasts();
4196  if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
4197  if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
4198  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
4199  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4200  return getCanonicalDecl(ME->getMemberDecl());
4201  return getCanonicalDecl(VD);
4202  }
4203  }
4204  if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
4205  if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4206  return getCanonicalDecl(ME->getMemberDecl());
4207  return nullptr;
4208 }
4209 
4210 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
4211  // Check test-expr for canonical form, save upper-bound UB, flags for
4212  // less/greater and for strict/non-strict comparison.
4213  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4214  // var relational-op b
4215  // b relational-op var
4216  //
4217  if (!S) {
4218  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
4219  return true;
4220  }
4221  S = getExprAsWritten(S);
4222  SourceLocation CondLoc = S->getLocStart();
4223  if (auto BO = dyn_cast<BinaryOperator>(S)) {
4224  if (BO->isRelationalOp()) {
4225  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
4226  return SetUB(BO->getRHS(),
4227  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
4228  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4229  BO->getSourceRange(), BO->getOperatorLoc());
4230  if (GetInitLCDecl(BO->getRHS()) == LCDecl)
4231  return SetUB(BO->getLHS(),
4232  (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
4233  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4234  BO->getSourceRange(), BO->getOperatorLoc());
4235  }
4236  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4237  if (CE->getNumArgs() == 2) {
4238  auto Op = CE->getOperator();
4239  switch (Op) {
4240  case OO_Greater:
4241  case OO_GreaterEqual:
4242  case OO_Less:
4243  case OO_LessEqual:
4244  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4245  return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4246  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4247  CE->getOperatorLoc());
4248  if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
4249  return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4250  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4251  CE->getOperatorLoc());
4252  break;
4253  default:
4254  break;
4255  }
4256  }
4257  }
4258  if (Dependent() || SemaRef.CurContext->isDependentContext())
4259  return false;
4260  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4261  << S->getSourceRange() << LCDecl;
4262  return true;
4263 }
4264 
4265 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
4266  // RHS of canonical loop form increment can be:
4267  // var + incr
4268  // incr + var
4269  // var - incr
4270  //
4271  RHS = RHS->IgnoreParenImpCasts();
4272  if (auto BO = dyn_cast<BinaryOperator>(RHS)) {
4273  if (BO->isAdditiveOp()) {
4274  bool IsAdd = BO->getOpcode() == BO_Add;
4275  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
4276  return SetStep(BO->getRHS(), !IsAdd);
4277  if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
4278  return SetStep(BO->getLHS(), false);
4279  }
4280  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4281  bool IsAdd = CE->getOperator() == OO_Plus;
4282  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4283  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4284  return SetStep(CE->getArg(1), !IsAdd);
4285  if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
4286  return SetStep(CE->getArg(0), false);
4287  }
4288  }
4289  if (Dependent() || SemaRef.CurContext->isDependentContext())
4290  return false;
4291  SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
4292  << RHS->getSourceRange() << LCDecl;
4293  return true;
4294 }
4295 
4296 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
4297  // Check incr-expr for canonical loop form and return true if it
4298  // does not conform.
4299  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4300  // ++var
4301  // var++
4302  // --var
4303  // var--
4304  // var += incr
4305  // var -= incr
4306  // var = var + incr
4307  // var = incr + var
4308  // var = var - incr
4309  //
4310  if (!S) {
4311  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4312  return true;
4313  }
4314  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4315  if (!ExprTemp->cleanupsHaveSideEffects())
4316  S = ExprTemp->getSubExpr();
4317 
4318  IncrementSrcRange = S->getSourceRange();
4319  S = S->IgnoreParens();
4320  if (auto UO = dyn_cast<UnaryOperator>(S)) {
4321  if (UO->isIncrementDecrementOp() &&
4322  GetInitLCDecl(UO->getSubExpr()) == LCDecl)
4323  return SetStep(
4324  SemaRef.ActOnIntegerConstant(UO->getLocStart(),
4325  (UO->isDecrementOp() ? -1 : 1)).get(),
4326  false);
4327  } else if (auto BO = dyn_cast<BinaryOperator>(S)) {
4328  switch (BO->getOpcode()) {
4329  case BO_AddAssign:
4330  case BO_SubAssign:
4331  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
4332  return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4333  break;
4334  case BO_Assign:
4335  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
4336  return CheckIncRHS(BO->getRHS());
4337  break;
4338  default:
4339  break;
4340  }
4341  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4342  switch (CE->getOperator()) {
4343  case OO_PlusPlus:
4344  case OO_MinusMinus:
4345  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4346  return SetStep(
4347  SemaRef.ActOnIntegerConstant(
4348  CE->getLocStart(),
4349  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(),
4350  false);
4351  break;
4352  case OO_PlusEqual:
4353  case OO_MinusEqual:
4354  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4355  return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4356  break;
4357  case OO_Equal:
4358  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4359  return CheckIncRHS(CE->getArg(1));
4360  break;
4361  default:
4362  break;
4363  }
4364  }
4365  if (Dependent() || SemaRef.CurContext->isDependentContext())
4366  return false;
4367  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
4368  << S->getSourceRange() << LCDecl;
4369  return true;
4370 }
4371 
4372 static ExprResult
4373 tryBuildCapture(Sema &SemaRef, Expr *Capture,
4374  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4375  if (SemaRef.CurContext->isDependentContext())
4376  return ExprResult(Capture);
4377  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
4378  return SemaRef.PerformImplicitConversion(
4379  Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
4380  /*AllowExplicit=*/true);
4381  auto I = Captures.find(Capture);
4382  if (I != Captures.end())
4383  return buildCapture(SemaRef, Capture, I->second);
4384  DeclRefExpr *Ref = nullptr;
4385  ExprResult Res = buildCapture(SemaRef, Capture, Ref);
4386  Captures[Capture] = Ref;
4387  return Res;
4388 }
4389 
4390 /// \brief Build the expression to calculate the number of iterations.
4391 Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
4392  Scope *S, const bool LimitedType,
4393  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
4394  ExprResult Diff;
4395  auto VarType = LCDecl->getType().getNonReferenceType();
4396  if (VarType->isIntegerType() || VarType->isPointerType() ||
4397  SemaRef.getLangOpts().CPlusPlus) {
4398  // Upper - Lower
4399  auto *UBExpr = TestIsLessOp ? UB : LB;
4400  auto *LBExpr = TestIsLessOp ? LB : UB;
4401  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4402  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4403  if (!Upper || !Lower)
4404  return nullptr;
4405 
4406  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4407 
4408  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4409  // BuildBinOp already emitted error, this one is to point user to upper
4410  // and lower bound, and to tell what is passed to 'operator-'.
4411  SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
4412  << Upper->getSourceRange() << Lower->getSourceRange();
4413  return nullptr;
4414  }
4415  }
4416 
4417  if (!Diff.isUsable())
4418  return nullptr;
4419 
4420  // Upper - Lower [- 1]
4421  if (TestIsStrictOp)
4422  Diff = SemaRef.BuildBinOp(
4423  S, DefaultLoc, BO_Sub, Diff.get(),
4424  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4425  if (!Diff.isUsable())
4426  return nullptr;
4427 
4428  // Upper - Lower [- 1] + Step
4429  auto NewStep = tryBuildCapture(SemaRef, Step, Captures);
4430  if (!NewStep.isUsable())
4431  return nullptr;
4432  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
4433  if (!Diff.isUsable())
4434  return nullptr;
4435 
4436  // Parentheses (for dumping/debugging purposes only).
4437  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4438  if (!Diff.isUsable())
4439  return nullptr;
4440 
4441  // (Upper - Lower [- 1] + Step) / Step
4442  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4443  if (!Diff.isUsable())
4444  return nullptr;
4445 
4446  // OpenMP runtime requires 32-bit or 64-bit loop variables.
4447  QualType Type = Diff.get()->getType();
4448  auto &C = SemaRef.Context;
4449  bool UseVarType = VarType->hasIntegerRepresentation() &&
4450  C.getTypeSize(Type) > C.getTypeSize(VarType);
4451  if (!Type->isIntegerType() || UseVarType) {
4452  unsigned NewSize =
4453  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
4454  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
4456  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
4457  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
4458  Diff = SemaRef.PerformImplicitConversion(
4459  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
4460  if (!Diff.isUsable())
4461  return nullptr;
4462  }
4463  }
4464  if (LimitedType) {
4465  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
4466  if (NewSize != C.getTypeSize(Type)) {
4467  if (NewSize < C.getTypeSize(Type)) {
4468  assert(NewSize == 64 && "incorrect loop var size");
4469  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4470  << InitSrcRange << ConditionSrcRange;
4471  }
4472  QualType NewType = C.getIntTypeForBitwidth(
4473  NewSize, Type->hasSignedIntegerRepresentation() ||
4474  C.getTypeSize(Type) < NewSize);
4475  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4476  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4477  Sema::AA_Converting, true);
4478  if (!Diff.isUsable())
4479  return nullptr;
4480  }
4481  }
4482  }
4483 
4484  return Diff.get();
4485 }
4486 
4487 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
4488  Scope *S, Expr *Cond,
4489  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
4490  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4491  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4492  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4493 
4494  auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
4495  auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
4496  if (!NewLB.isUsable() || !NewUB.isUsable())
4497  return nullptr;
4498 
4499  auto CondExpr = SemaRef.BuildBinOp(
4500  S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4501  : (TestIsStrictOp ? BO_GT : BO_GE),
4502  NewLB.get(), NewUB.get());
4503  if (CondExpr.isUsable()) {
4504  if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4505  SemaRef.Context.BoolTy))
4506  CondExpr = SemaRef.PerformImplicitConversion(
4507  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4508  /*AllowExplicit=*/true);
4509  }
4510  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4511  // Otherwise use original loop conditon and evaluate it in runtime.
4512  return CondExpr.isUsable() ? CondExpr.get() : Cond;
4513 }
4514 
4515 /// \brief Build reference expression to the counter be used for codegen.
4516 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
4517  llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const {
4518  auto *VD = dyn_cast<VarDecl>(LCDecl);
4519  if (!VD) {
4520  VD = SemaRef.IsOpenMPCapturedDecl(LCDecl);
4521  auto *Ref = buildDeclRefExpr(
4522  SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4523  DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4524  // If the loop control decl is explicitly marked as private, do not mark it
4525  // as captured again.
4526  if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4527  Captures.insert(std::make_pair(LCRef, Ref));
4528  return Ref;
4529  }
4530  return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4531  DefaultLoc);
4532 }
4533 
4534 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
4535  if (LCDecl && !LCDecl->isInvalidDecl()) {
4536  auto Type = LCDecl->getType().getNonReferenceType();
4537  auto *PrivateVar =
4538  buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(),
4539  LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr);
4540  if (PrivateVar->isInvalidDecl())
4541  return nullptr;
4542  return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4543  }
4544  return nullptr;
4545 }
4546 
4547 /// \brief Build initization of the counter be used for codegen.
4549 
4550 /// \brief Build step of the counter be used for codegen.
4551 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
4552 
4553 /// \brief Iteration space of a single for loop.
4554 struct LoopIterationSpace final {
4555  /// \brief Condition of the loop.
4556  Expr *PreCond = nullptr;
4557  /// \brief This expression calculates the number of iterations in the loop.
4558  /// It is always possible to calculate it before starting the loop.
4559  Expr *NumIterations = nullptr;
4560  /// \brief The loop counter variable.
4561  Expr *CounterVar = nullptr;
4562  /// \brief Private loop counter variable.
4563  Expr *PrivateCounterVar = nullptr;
4564  /// \brief This is initializer for the initial value of #CounterVar.
4565  Expr *CounterInit = nullptr;
4566  /// \brief This is step for the #CounterVar used to generate its update:
4567  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4568  Expr *CounterStep = nullptr;
4569  /// \brief Should step be subtracted?
4570  bool Subtract = false;
4571  /// \brief Source range of the loop init.
4572  SourceRange InitSrcRange;
4573  /// \brief Source range of the loop condition.
4574  SourceRange CondSrcRange;
4575  /// \brief Source range of the loop increment.
4576  SourceRange IncSrcRange;
4577 };
4578 
4579 } // namespace
4580 
4582  assert(getLangOpts().OpenMP && "OpenMP is not active.");
4583  assert(Init && "Expected loop in canonical form.");
4584  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
4585  if (AssociatedLoops > 0 &&
4586  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
4587  OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4588  if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) {
4589  if (auto *D = ISC.GetLoopDecl()) {
4590  auto *VD = dyn_cast<VarDecl>(D);
4591  if (!VD) {
4592  if (auto *Private = IsOpenMPCapturedDecl(D))
4593  VD = Private;
4594  else {
4595  auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(),
4596  /*WithInit=*/false);
4597  VD = cast<VarDecl>(Ref->getDecl());
4598  }
4599  }
4600  DSAStack->addLoopControlVariable(D, VD);
4601  }
4602  }
4603  DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4604  }
4605 }
4606 
4607 /// \brief Called on a for stmt to check and extract its iteration space
4608 /// for further processing (such as collapsing).
4610  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4611  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4612  Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
4613  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4614  LoopIterationSpace &ResultIterSpace,
4615  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4616  // OpenMP [2.6, Canonical Loop Form]
4617  // for (init-expr; test-expr; incr-expr) structured-block
4618  auto For = dyn_cast_or_null<ForStmt>(S);
4619  if (!For) {
4620  SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
4621  << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4622  << getOpenMPDirectiveName(DKind) << NestedLoopCount
4623  << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4624  if (NestedLoopCount > 1) {
4625  if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4626  SemaRef.Diag(DSA.getConstructLoc(),
4627  diag::note_omp_collapse_ordered_expr)
4628  << 2 << CollapseLoopCountExpr->getSourceRange()
4629  << OrderedLoopCountExpr->getSourceRange();
4630  else if (CollapseLoopCountExpr)
4631  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4632  diag::note_omp_collapse_ordered_expr)
4633  << 0 << CollapseLoopCountExpr->getSourceRange();
4634  else
4635  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4636  diag::note_omp_collapse_ordered_expr)
4637  << 1 << OrderedLoopCountExpr->getSourceRange();
4638  }
4639  return true;
4640  }
4641  assert(For->getBody());
4642 
4643  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4644 
4645  // Check init.
4646  auto Init = For->getInit();
4647  if (ISC.CheckInit(Init))
4648  return true;
4649 
4650  bool HasErrors = false;
4651 
4652  // Check loop variable's type.
4653  if (auto *LCDecl = ISC.GetLoopDecl()) {
4654  auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
4655 
4656  // OpenMP [2.6, Canonical Loop Form]
4657  // Var is one of the following:
4658  // A variable of signed or unsigned integer type.
4659  // For C++, a variable of a random access iterator type.
4660  // For C, a variable of a pointer type.
4661  auto VarType = LCDecl->getType().getNonReferenceType();
4662  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4663  !VarType->isPointerType() &&
4664  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4665  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4666  << SemaRef.getLangOpts().CPlusPlus;
4667  HasErrors = true;
4668  }
4669 
4670  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4671  // a Construct
4672  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4673  // parallel for construct is (are) private.
4674  // The loop iteration variable in the associated for-loop of a simd
4675  // construct with just one associated for-loop is linear with a
4676  // constant-linear-step that is the increment of the associated for-loop.
4677  // Exclude loop var from the list of variables with implicitly defined data
4678  // sharing attributes.
4679  VarsWithImplicitDSA.erase(LCDecl);
4680 
4681  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4682  // in a Construct, C/C++].
4683  // The loop iteration variable in the associated for-loop of a simd
4684  // construct with just one associated for-loop may be listed in a linear
4685  // clause with a constant-linear-step that is the increment of the
4686  // associated for-loop.
4687  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4688  // parallel for construct may be listed in a private or lastprivate clause.
4689  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4690  // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4691  // declared in the loop and it is predetermined as a private.
4692  auto PredeterminedCKind =
4693  isOpenMPSimdDirective(DKind)
4694  ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4695  : OMPC_private;
4696  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4697  DVar.CKind != PredeterminedCKind) ||
4698  ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4699  isOpenMPDistributeDirective(DKind)) &&
4700  !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4701  DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4702  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4703  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4704  << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4705  << getOpenMPClauseName(PredeterminedCKind);
4706  if (DVar.RefExpr == nullptr)
4707  DVar.CKind = PredeterminedCKind;
4708  ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4709  HasErrors = true;
4710  } else if (LoopDeclRefExpr != nullptr) {
4711  // Make the loop iteration variable private (for worksharing constructs),
4712  // linear (for simd directives with the only one associated loop) or
4713  // lastprivate (for simd directives with several collapsed or ordered
4714  // loops).
4715  if (DVar.CKind == OMPC_unknown)
4716  DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4717  [](OpenMPDirectiveKind) -> bool { return true; },
4718  /*FromParent=*/false);
4719  DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4720  }
4721 
4722  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
4723 
4724  // Check test-expr.
4725  HasErrors |= ISC.CheckCond(For->getCond());
4726 
4727  // Check incr-expr.
4728  HasErrors |= ISC.CheckInc(For->getInc());
4729  }
4730 
4731  if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4732  return HasErrors;
4733 
4734  // Build the loop's iteration space representation.
4735  ResultIterSpace.PreCond =
4736  ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4737  ResultIterSpace.NumIterations = ISC.BuildNumIterations(
4738  DSA.getCurScope(),
4739  (isOpenMPWorksharingDirective(DKind) ||
4741  Captures);
4742  ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
4743  ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
4744  ResultIterSpace.CounterInit = ISC.BuildCounterInit();
4745  ResultIterSpace.CounterStep = ISC.BuildCounterStep();
4746  ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
4747  ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
4748  ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
4749  ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
4750 
4751  HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4752  ResultIterSpace.NumIterations == nullptr ||
4753  ResultIterSpace.CounterVar == nullptr ||
4754  ResultIterSpace.PrivateCounterVar == nullptr ||
4755  ResultIterSpace.CounterInit == nullptr ||
4756  ResultIterSpace.CounterStep == nullptr);
4757 
4758  return HasErrors;
4759 }
4760 
4761 /// \brief Build 'VarRef = Start.
4762 static ExprResult
4764  ExprResult Start,
4765  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4766  // Build 'VarRef = Start.
4767  auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4768  if (!NewStart.isUsable())
4769  return ExprError();
4770  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4771  VarRef.get()->getType())) {
4772  NewStart = SemaRef.PerformImplicitConversion(
4773  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4774  /*AllowExplicit=*/true);
4775  if (!NewStart.isUsable())
4776  return ExprError();
4777  }
4778 
4779  auto Init =
4780  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4781  return Init;
4782 }
4783 
4784 /// \brief Build 'VarRef = Start + Iter * Step'.
4785 static ExprResult
4787  ExprResult VarRef, ExprResult Start, ExprResult Iter,
4788  ExprResult Step, bool Subtract,
4789  llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) {
4790  // Add parentheses (for debugging purposes only).
4791  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4792  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4793  !Step.isUsable())
4794  return ExprError();
4795 
4796  ExprResult NewStep = Step;
4797  if (Captures)
4798  NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4799  if (NewStep.isInvalid())
4800  return ExprError();
4801  ExprResult Update =
4802  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4803  if (!Update.isUsable())
4804  return ExprError();
4805 
4806  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4807  // 'VarRef = Start (+|-) Iter * Step'.
4808  ExprResult NewStart = Start;
4809  if (Captures)
4810  NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4811  if (NewStart.isInvalid())
4812  return ExprError();
4813 
4814  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4815  ExprResult SavedUpdate = Update;
4816  ExprResult UpdateVal;
4817  if (VarRef.get()->getType()->isOverloadableType() ||
4818  NewStart.get()->getType()->isOverloadableType() ||
4819  Update.get()->getType()->isOverloadableType()) {
4820  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4821  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4822  Update =
4823  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4824  if (Update.isUsable()) {
4825  UpdateVal =
4826  SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4827  VarRef.get(), SavedUpdate.get());
4828  if (UpdateVal.isUsable()) {
4829  Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4830  UpdateVal.get());
4831  }
4832  }
4833  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4834  }
4835 
4836  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4837  if (!Update.isUsable() || !UpdateVal.isUsable()) {
4838  Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4839  NewStart.get(), SavedUpdate.get());
4840  if (!Update.isUsable())
4841  return ExprError();
4842 
4843  if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4844  VarRef.get()->getType())) {
4845  Update = SemaRef.PerformImplicitConversion(
4846  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4847  if (!Update.isUsable())
4848  return ExprError();
4849  }
4850 
4851  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4852  }
4853  return Update;
4854 }
4855 
4856 /// \brief Convert integer expression \a E to make it have at least \a Bits
4857 /// bits.
4858 static ExprResult WidenIterationCount(unsigned Bits, Expr *E,
4859  Sema &SemaRef) {
4860  if (E == nullptr)
4861  return ExprError();
4862  auto &C = SemaRef.Context;
4863  QualType OldType = E->getType();
4864  unsigned HasBits = C.getTypeSize(OldType);
4865  if (HasBits >= Bits)
4866  return ExprResult(E);
4867  // OK to convert to signed, because new type has more bits than old.
4868  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4869  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4870  true);
4871 }
4872 
4873 /// \brief Check if the given expression \a E is a constant integer that fits
4874 /// into \a Bits bits.
4875 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
4876  if (E == nullptr)
4877  return false;
4878  llvm::APSInt Result;
4879  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4880  return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4881  return false;
4882 }
4883 
4884 /// Build preinits statement for the given declarations.
4886  SmallVectorImpl<Decl *> &PreInits) {
4887  if (!PreInits.empty()) {
4888  return new (Context) DeclStmt(
4889  DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4891  }
4892  return nullptr;
4893 }
4894 
4895 /// Build preinits statement for the given declarations.
4897  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4898  if (!Captures.empty()) {
4899  SmallVector<Decl *, 16> PreInits;
4900  for (auto &Pair : Captures)
4901  PreInits.push_back(Pair.second->getDecl());
4902  return buildPreInits(Context, PreInits);
4903  }
4904  return nullptr;
4905 }
4906 
4907 /// Build postupdate expression for the given list of postupdates expressions.
4908 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4909  Expr *PostUpdate = nullptr;
4910  if (!PostUpdates.empty()) {
4911  for (auto *E : PostUpdates) {
4912  Expr *ConvE = S.BuildCStyleCastExpr(
4913  E->getExprLoc(),
4915  E->getExprLoc(), E)
4916  .get();
4917  PostUpdate = PostUpdate
4918  ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4919  PostUpdate, ConvE)
4920  .get()
4921  : ConvE;
4922  }
4923  }
4924  return PostUpdate;
4925 }
4926 
4927 /// \brief Called on a for stmt to check itself and nested loops (if any).
4928 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4929 /// number of collapsed loops otherwise.
4930 static unsigned
4931 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4932  Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4933  DSAStackTy &DSA,
4934  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4936  unsigned NestedLoopCount = 1;
4937  if (CollapseLoopCountExpr) {
4938  // Found 'collapse' clause - calculate collapse number.
4939  llvm::APSInt Result;
4940  if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4941  NestedLoopCount = Result.getLimitedValue();
4942  }
4943  if (OrderedLoopCountExpr) {
4944  // Found 'ordered' clause - calculate collapse number.
4945  llvm::APSInt Result;
4946  if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
4947  if (Result.getLimitedValue() < NestedLoopCount) {
4948  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4949  diag::err_omp_wrong_ordered_loop_count)
4950  << OrderedLoopCountExpr->getSourceRange();
4951  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4952  diag::note_collapse_loop_count)
4953  << CollapseLoopCountExpr->getSourceRange();
4954  }
4955  NestedLoopCount = Result.getLimitedValue();
4956  }
4957  }
4958  // This is helper routine for loop directives (e.g., 'for', 'simd',
4959  // 'for simd', etc.).
4960  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4962  IterSpaces.resize(NestedLoopCount);
4963  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4964  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4965  if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
4966  NestedLoopCount, CollapseLoopCountExpr,
4967  OrderedLoopCountExpr, VarsWithImplicitDSA,
4968  IterSpaces[Cnt], Captures))
4969  return 0;
4970  // Move on to the next nested for loop, or to the loop body.
4971  // OpenMP [2.8.1, simd construct, Restrictions]
4972  // All loops associated with the construct must be perfectly nested; that
4973  // is, there must be no intervening code nor any OpenMP directive between
4974  // any two loops.
4975  CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4976  }
4977 
4978  Built.clear(/* size */ NestedLoopCount);
4979 
4980  if (SemaRef.CurContext->isDependentContext())
4981  return NestedLoopCount;
4982 
4983  // An example of what is generated for the following code:
4984  //
4985  // #pragma omp simd collapse(2) ordered(2)
4986  // for (i = 0; i < NI; ++i)
4987  // for (k = 0; k < NK; ++k)
4988  // for (j = J0; j < NJ; j+=2) {
4989  // <loop body>
4990  // }
4991  //
4992  // We generate the code below.
4993  // Note: the loop body may be outlined in CodeGen.
4994  // Note: some counters may be C++ classes, operator- is used to find number of
4995  // iterations and operator+= to calculate counter value.
4996  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4997  // or i64 is currently supported).
4998  //
4999  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
5000  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
5001  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
5002  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
5003  // // similar updates for vars in clauses (e.g. 'linear')
5004  // <loop body (using local i and j)>
5005  // }
5006  // i = NI; // assign final values of counters
5007  // j = NJ;
5008  //
5009 
5010  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
5011  // the iteration counts of the collapsed for loops.
5012  // Precondition tests if there is at least one iteration (all conditions are
5013  // true).
5014  auto PreCond = ExprResult(IterSpaces[0].PreCond);
5015  auto N0 = IterSpaces[0].NumIterations;
5016  ExprResult LastIteration32 = WidenIterationCount(
5017  32 /* Bits */, SemaRef.PerformImplicitConversion(
5018  N0->IgnoreImpCasts(), N0->getType(),
5019  Sema::AA_Converting, /*AllowExplicit=*/true)
5020  .get(),
5021  SemaRef);
5022  ExprResult LastIteration64 = WidenIterationCount(
5023  64 /* Bits */, SemaRef.PerformImplicitConversion(
5024  N0->IgnoreImpCasts(), N0->getType(),
5025  Sema::AA_Converting, /*AllowExplicit=*/true)
5026  .get(),
5027  SemaRef);
5028 
5029  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
5030  return NestedLoopCount;
5031 
5032  auto &C = SemaRef.Context;
5033  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
5034 
5035  Scope *CurScope = DSA.getCurScope();
5036  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
5037  if (PreCond.isUsable()) {
5038  PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd,
5039  PreCond.get(), IterSpaces[Cnt].PreCond);
5040  }
5041  auto N = IterSpaces[Cnt].NumIterations;
5042  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
5043  if (LastIteration32.isUsable())
5044  LastIteration32 = SemaRef.BuildBinOp(
5045  CurScope, SourceLocation(), BO_Mul, LastIteration32.get(),
5046  SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
5048  /*AllowExplicit=*/true)
5049  .get());
5050  if (LastIteration64.isUsable())
5051  LastIteration64 = SemaRef.BuildBinOp(
5052  CurScope, SourceLocation(), BO_Mul, LastIteration64.get(),
5053  SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
5055  /*AllowExplicit=*/true)
5056  .get());
5057  }
5058 
5059  // Choose either the 32-bit or 64-bit version.
5060  ExprResult LastIteration = LastIteration64;
5061  if (LastIteration32.isUsable() &&
5062  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
5063  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
5064  FitsInto(
5065  32 /* Bits */,
5066  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
5067  LastIteration64.get(), SemaRef)))
5068  LastIteration = LastIteration32;
5069  QualType VType = LastIteration.get()->getType();
5070  QualType RealVType = VType;
5071  QualType StrideVType = VType;
5072  if (isOpenMPTaskLoopDirective(DKind)) {
5073  VType =
5074  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
5075  StrideVType =
5076  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
5077  }
5078 
5079  if (!LastIteration.isUsable())
5080  return 0;
5081 
5082  // Save the number of iterations.
5083  ExprResult NumIterations = LastIteration;
5084  {
5085  LastIteration = SemaRef.BuildBinOp(
5086  CurScope, SourceLocation(), BO_Sub, LastIteration.get(),
5087  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5088  if (!LastIteration.isUsable())
5089  return 0;
5090  }
5091 
5092  // Calculate the last iteration number beforehand instead of doing this on
5093  // each iteration. Do not do this if the number of iterations may be kfold-ed.
5094  llvm::APSInt Result;
5095  bool IsConstant =
5096  LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
5097  ExprResult CalcLastIteration;
5098  if (!IsConstant) {
5099  ExprResult SaveRef =
5100  tryBuildCapture(SemaRef, LastIteration.get(), Captures);
5101  LastIteration = SaveRef;
5102 
5103  // Prepare SaveRef + 1.
5104  NumIterations = SemaRef.BuildBinOp(
5105  CurScope, SourceLocation(), BO_Add, SaveRef.get(),
5106  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5107  if (!NumIterations.isUsable())
5108  return 0;
5109  }
5110 
5111  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
5112 
5113  // Build variables passed into runtime, nesessary for worksharing directives.
5114  ExprResult LB, UB, IL, ST, EUB, PrevLB, PrevUB;
5116  isOpenMPDistributeDirective(DKind)) {
5117  // Lower bound variable, initialized with zero.
5118  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
5119  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
5120  SemaRef.AddInitializerToDecl(
5121  LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5122  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
5123 
5124  // Upper bound variable, initialized with last iteration number.
5125  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
5126  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
5127  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
5128  /*DirectInit*/ false,
5129  /*TypeMayContainAuto*/ false);
5130 
5131  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
5132  // This will be used to implement clause 'lastprivate'.
5133  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
5134  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
5135  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
5136  SemaRef.AddInitializerToDecl(
5137  ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5138  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
5139 
5140  // Stride variable returned by runtime (we initialize it to 1 by default).
5141  VarDecl *STDecl =
5142  buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
5143  ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
5144  SemaRef.AddInitializerToDecl(
5145  STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
5146  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
5147 
5148  // Build expression: UB = min(UB, LastIteration)
5149  // It is nesessary for CodeGen of directives with static scheduling.
5150  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
5151  UB.get(), LastIteration.get());
5152  ExprResult CondOp = SemaRef.ActOnConditionalOp(
5153  InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
5154  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
5155  CondOp.get());
5156  EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
5157 
5158  // If we have a combined directive that combines 'distribute', 'for' or
5159  // 'simd' we need to be able to access the bounds of the schedule of the
5160  // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
5161  // by scheduling 'distribute' have to be passed to the schedule of 'for'.
5162  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5163  auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5164 
5165  // We expect to have at least 2 more parameters than the 'parallel'
5166  // directive does - the lower and upper bounds of the previous schedule.
5167  assert(CD->getNumParams() >= 4 &&
5168  "Unexpected number of parameters in loop combined directive");
5169 
5170  // Set the proper type for the bounds given what we learned from the
5171  // enclosed loops.
5172  auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
5173  auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
5174 
5175  // Previous lower and upper bounds are obtained from the region
5176  // parameters.
5177  PrevLB =
5178  buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
5179  PrevUB =
5180  buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
5181  }
5182  }
5183 
5184  // Build the iteration variable and its initialization before loop.
5185  ExprResult IV;
5186  ExprResult Init;
5187  {
5188  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
5189  IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
5190  Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
5191  isOpenMPTaskLoopDirective(DKind) ||
5193  ? LB.get()
5194  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5195  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5196  Init = SemaRef.ActOnFinishFullExpr(Init.get());
5197  }
5198 
5199  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
5200  SourceLocation CondLoc;
5201  ExprResult Cond =
5202  (isOpenMPWorksharingDirective(DKind) ||
5204  ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
5205  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5206  NumIterations.get());
5207 
5208  // Loop increment (IV = IV + 1)
5209  SourceLocation IncLoc;
5210  ExprResult Inc =
5211  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5212  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
5213  if (!Inc.isUsable())
5214  return 0;
5215  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
5216  Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
5217  if (!Inc.isUsable())
5218  return 0;
5219 
5220  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
5221  // Used for directives with static scheduling.
5222  ExprResult NextLB, NextUB;
5224  isOpenMPDistributeDirective(DKind)) {
5225  // LB + ST
5226  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
5227  if (!NextLB.isUsable())
5228  return 0;
5229  // LB = LB + ST
5230  NextLB =
5231  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
5232  NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
5233  if (!NextLB.isUsable())
5234  return 0;
5235  // UB + ST
5236  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
5237  if (!NextUB.isUsable())
5238  return 0;
5239  // UB = UB + ST
5240  NextUB =
5241  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
5242  NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
5243  if (!NextUB.isUsable())
5244  return 0;
5245  }
5246 
5247  // Build updates and final values of the loop counters.
5248  bool HasErrors = false;
5249  Built.Counters.resize(NestedLoopCount);
5250  Built.Inits.resize(NestedLoopCount);
5251  Built.Updates.resize(NestedLoopCount);
5252  Built.Finals.resize(NestedLoopCount);
5253  SmallVector<Expr *, 4> LoopMultipliers;
5254  {
5255  ExprResult Div;
5256  // Go from inner nested loop to outer.
5257  for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5258  LoopIterationSpace &IS = IterSpaces[Cnt];
5259  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
5260  // Build: Iter = (IV / Div) % IS.NumIters
5261  // where Div is product of previous iterations' IS.NumIters.
5262  ExprResult Iter;
5263  if (Div.isUsable()) {
5264  Iter =
5265  SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
5266  } else {
5267  Iter = IV;
5268  assert((Cnt == (int)NestedLoopCount - 1) &&
5269  "unusable div expected on first iteration only");
5270  }
5271 
5272  if (Cnt != 0 && Iter.isUsable())
5273  Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
5274  IS.NumIterations);
5275  if (!Iter.isUsable()) {
5276  HasErrors = true;
5277  break;
5278  }
5279 
5280  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
5281  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5282  auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(),
5283  IS.CounterVar->getExprLoc(),
5284  /*RefersToCapture=*/true);
5285  ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
5286  IS.CounterInit, Captures);
5287  if (!Init.isUsable()) {
5288  HasErrors = true;
5289  break;
5290  }
5291  ExprResult Update = BuildCounterUpdate(
5292  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5293  IS.CounterStep, IS.Subtract, &Captures);
5294  if (!Update.isUsable()) {
5295  HasErrors = true;
5296  break;
5297  }
5298 
5299  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
5301  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5302  IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5303  if (!Final.isUsable()) {
5304  HasErrors = true;
5305  break;
5306  }
5307 
5308  // Build Div for the next iteration: Div <- Div * IS.NumIters
5309  if (Cnt != 0) {
5310  if (Div.isUnset())
5311  Div = IS.NumIterations;
5312  else
5313  Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
5314  IS.NumIterations);
5315 
5316  // Add parentheses (for debugging purposes only).
5317  if (Div.isUsable())
5318  Div = tryBuildCapture(SemaRef, Div.get(), Captures);
5319  if (!Div.isUsable()) {
5320  HasErrors = true;
5321  break;
5322  }
5323  LoopMultipliers.push_back(Div.get());
5324  }
5325  if (!Update.isUsable() || !Final.isUsable()) {
5326  HasErrors = true;
5327  break;
5328  }
5329  // Save results
5330  Built.Counters[Cnt] = IS.CounterVar;
5331  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
5332  Built.Inits[Cnt] = Init.get();
5333  Built.Updates[Cnt] = Update.get();
5334  Built.Finals[Cnt] = Final.get();
5335  }
5336  }
5337 
5338  if (HasErrors)
5339  return 0;
5340 
5341  // Save results
5342  Built.IterationVarRef = IV.get();
5343  Built.LastIteration = LastIteration.get();
5344  Built.NumIterations = NumIterations.get();
5345  Built.CalcLastIteration =
5346  SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
5347  Built.PreCond = PreCond.get();
5348  Built.PreInits = buildPreInits(C, Captures);
5349  Built.Cond = Cond.get();
5350  Built.Init = Init.get();
5351  Built.Inc = Inc.get();
5352  Built.LB = LB.get();
5353  Built.UB = UB.get();
5354  Built.IL = IL.get();
5355  Built.ST = ST.get();
5356  Built.EUB = EUB.get();
5357  Built.NLB = NextLB.get();
5358  Built.NUB = NextUB.get();
5359  Built.PrevLB = PrevLB.get();
5360  Built.PrevUB = PrevUB.get();
5361 
5362  Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
5363  // Fill data for doacross depend clauses.
5364  for (auto Pair : DSA.getDoacrossDependClauses()) {
5365  if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
5366  Pair.first->setCounterValue(CounterVal);
5367  else {
5368  if (NestedLoopCount != Pair.second.size() ||
5369  NestedLoopCount != LoopMultipliers.size() + 1) {
5370  // Erroneous case - clause has some problems.
5371  Pair.first->setCounterValue(CounterVal);
5372  continue;
5373  }
5374  assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink);
5375  auto I = Pair.second.rbegin();
5376  auto IS = IterSpaces.rbegin();
5377  auto ILM = LoopMultipliers.rbegin();
5378  Expr *UpCounterVal = CounterVal;
5379  Expr *Multiplier = nullptr;
5380  for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5381  if (I->first) {
5382  assert(IS->CounterStep);
5383  Expr *NormalizedOffset =
5384  SemaRef
5385  .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
5386  I->first, IS->CounterStep)
5387  .get();
5388  if (Multiplier) {
5389  NormalizedOffset =
5390  SemaRef
5391  .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
5392  NormalizedOffset, Multiplier)
5393  .get();
5394  }
5395  assert(I->second == OO_Plus || I->second == OO_Minus);
5396  BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub;
5397  UpCounterVal =
5398  SemaRef.BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
5399  UpCounterVal, NormalizedOffset).get();
5400  }
5401  Multiplier = *ILM;
5402  ++I;
5403  ++IS;
5404  ++ILM;
5405  }
5406  Pair.first->setCounterValue(UpCounterVal);
5407  }
5408  }
5409 
5410  return NestedLoopCount;
5411 }
5412 
5414  auto CollapseClauses =
5415  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5416  if (CollapseClauses.begin() != CollapseClauses.end())
5417  return (*CollapseClauses.begin())->getNumForLoops();
5418  return nullptr;
5419 }
5420 
5422  auto OrderedClauses =
5423  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5424  if (OrderedClauses.begin() != OrderedClauses.end())
5425  return (*OrderedClauses.begin())->getNumForLoops();
5426  return nullptr;
5427 }
5428 
5430  const ArrayRef<OMPClause *> Clauses) {
5431  OMPSafelenClause *Safelen = nullptr;
5432  OMPSimdlenClause *Simdlen = nullptr;
5433 
5434  for (auto *Clause : Clauses) {
5435  if (Clause->getClauseKind() == OMPC_safelen)
5436  Safelen = cast<OMPSafelenClause>(Clause);
5437  else if (Clause->getClauseKind() == OMPC_simdlen)
5438  Simdlen = cast<OMPSimdlenClause>(Clause);
5439  if (Safelen && Simdlen)
5440  break;
5441  }
5442 
5443  if (Simdlen && Safelen) {
5444  llvm::APSInt SimdlenRes, SafelenRes;
5445  auto SimdlenLength = Simdlen->getSimdlen();
5446  auto SafelenLength = Safelen->getSafelen();
5447  if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5448  SimdlenLength->isInstantiationDependent() ||
5449  SimdlenLength->containsUnexpandedParameterPack())
5450  return false;
5451  if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5452  SafelenLength->isInstantiationDependent() ||
5453  SafelenLength->containsUnexpandedParameterPack())
5454  return false;
5455  SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5456  SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5457  // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5458  // If both simdlen and safelen clauses are specified, the value of the
5459  // simdlen parameter must be less than or equal to the value of the safelen
5460  // parameter.
5461  if (SimdlenRes > SafelenRes) {
5462  S.Diag(SimdlenLength->getExprLoc(),
5463  diag::err_omp_wrong_simdlen_safelen_values)
5464  << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5465  return true;
5466  }
5467  }
5468  return false;
5469 }
5470 
5472  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5473  SourceLocation EndLoc,
5474  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5475  if (!AStmt)
5476  return StmtError();
5477 
5478  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5480  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5481  // define the nested loops number.
5482  unsigned NestedLoopCount = CheckOpenMPLoop(
5483  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5484  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5485  if (NestedLoopCount == 0)
5486  return StmtError();
5487 
5488  assert((CurContext->isDependentContext() || B.builtAll()) &&
5489  "omp simd loop exprs were not built");
5490 
5491  if (!CurContext->isDependentContext()) {
5492  // Finalize the clauses that need pre-built expressions for CodeGen.
5493  for (auto C : Clauses) {
5494  if (auto LC = dyn_cast<OMPLinearClause>(C))
5495  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5496  B.NumIterations, *this, CurScope,
5497  DSAStack))
5498  return StmtError();
5499  }
5500  }
5501 
5502  if (checkSimdlenSafelenSpecified(*this, Clauses))
5503  return StmtError();
5504 
5506  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5507  Clauses, AStmt, B);
5508 }
5509 
5511  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5512  SourceLocation EndLoc,
5513  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5514  if (!AStmt)
5515  return StmtError();
5516 
5517  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5519  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5520  // define the nested loops number.
5521  unsigned NestedLoopCount = CheckOpenMPLoop(
5522  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5523  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5524  if (NestedLoopCount == 0)
5525  return StmtError();
5526 
5527  assert((CurContext->isDependentContext() || B.builtAll()) &&
5528  "omp for loop exprs were not built");
5529 
5530  if (!CurContext->isDependentContext()) {
5531  // Finalize the clauses that need pre-built expressions for CodeGen.
5532  for (auto C : Clauses) {
5533  if (auto LC = dyn_cast<OMPLinearClause>(C))
5534  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5535  B.NumIterations, *this, CurScope,
5536  DSAStack))
5537  return StmtError();
5538  }
5539  }
5540 
5542  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5543  Clauses, AStmt, B, DSAStack->isCancelRegion());
5544 }
5545 
5547  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5548  SourceLocation EndLoc,
5549  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5550  if (!AStmt)
5551  return StmtError();
5552 
5553  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5555  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5556  // define the nested loops number.
5557  unsigned NestedLoopCount =
5558  CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5559  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5560  VarsWithImplicitDSA, B);
5561  if (NestedLoopCount == 0)
5562  return StmtError();
5563 
5564  assert((CurContext->isDependentContext() || B.builtAll()) &&
5565  "omp for simd loop exprs were not built");
5566 
5567  if (!CurContext->isDependentContext()) {
5568  // Finalize the clauses that need pre-built expressions for CodeGen.
5569  for (auto C : Clauses) {
5570  if (auto LC = dyn_cast<OMPLinearClause>(C))
5571  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5572  B.NumIterations, *this, CurScope,
5573  DSAStack))
5574  return StmtError();
5575  }
5576  }
5577 
5578  if (checkSimdlenSafelenSpecified(*this, Clauses))
5579  return StmtError();
5580 
5582  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5583  Clauses, AStmt, B);
5584 }
5585 
5587  Stmt *AStmt,
5588  SourceLocation StartLoc,
5589  SourceLocation EndLoc) {
5590  if (!AStmt)
5591  return StmtError();
5592 
5593  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5594  auto BaseStmt = AStmt;
5595  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5596  BaseStmt = CS->getCapturedStmt();
5597  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5598  auto S = C->children();
5599  if (S.begin() == S.end())
5600  return StmtError();
5601  // All associated statements must be '#pragma omp section' except for
5602  // the first one.
5603  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5604  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5605  if (SectionStmt)
5606  Diag(SectionStmt->getLocStart(),
5607  diag::err_omp_sections_substmt_not_section);
5608  return StmtError();
5609  }
5610  cast<OMPSectionDirective>(SectionStmt)
5611  ->setHasCancel(DSAStack->isCancelRegion());
5612  }
5613  } else {
5614  Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5615  return StmtError();
5616  }
5617 
5619 
5620  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5621  DSAStack->isCancelRegion());
5622 }
5623 
5625  SourceLocation StartLoc,
5626  SourceLocation EndLoc) {
5627  if (!AStmt)
5628  return StmtError();
5629 
5630  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5631 
5633  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5634 
5635  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5636  DSAStack->isCancelRegion());
5637 }
5638 
5640  Stmt *AStmt,
5641  SourceLocation StartLoc,
5642  SourceLocation EndLoc) {
5643  if (!AStmt)
5644  return StmtError();
5645 
5646  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5647 
5649 
5650  // OpenMP [2.7.3, single Construct, Restrictions]
5651  // The copyprivate clause must not be used with the nowait clause.
5652  OMPClause *Nowait = nullptr;
5653  OMPClause *Copyprivate = nullptr;
5654  for (auto *Clause : Clauses) {
5655  if (Clause->getClauseKind() == OMPC_nowait)
5656  Nowait = Clause;
5657  else if (Clause->getClauseKind() == OMPC_copyprivate)
5658  Copyprivate = Clause;
5659  if (Copyprivate && Nowait) {
5660  Diag(Copyprivate->getLocStart(),
5661  diag::err_omp_single_copyprivate_with_nowait);
5662  Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
5663  return StmtError();
5664  }
5665  }
5666 
5667  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5668 }
5669 
5671  SourceLocation StartLoc,
5672  SourceLocation EndLoc) {
5673  if (!AStmt)
5674  return StmtError();
5675 
5676  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5677 
5679 
5680  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5681 }
5682 
5684  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5685  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5686  if (!AStmt)
5687  return StmtError();
5688 
5689  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5690 
5691  bool ErrorFound = false;
5692  llvm::APSInt Hint;
5693  SourceLocation HintLoc;
5694  bool DependentHint = false;
5695  for (auto *C : Clauses) {
5696  if (C->getClauseKind() == OMPC_hint) {
5697  if (!DirName.getName()) {
5698  Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5699  ErrorFound = true;
5700  }
5701  Expr *E = cast<OMPHintClause>(C)->getHint();
5702  if (E->isTypeDependent() || E->isValueDependent() ||
5704  DependentHint = true;
5705  else {
5706  Hint = E->EvaluateKnownConstInt(Context);
5707  HintLoc = C->getLocStart();
5708  }
5709  }
5710  }
5711  if (ErrorFound)
5712  return StmtError();
5713  auto Pair = DSAStack->getCriticalWithHint(DirName);
5714  if (Pair.first && DirName.getName() && !DependentHint) {
5715  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5716  Diag(StartLoc, diag::err_omp_critical_with_hint);
5717  if (HintLoc.isValid()) {
5718  Diag(HintLoc, diag::note_omp_critical_hint_here)
5719  << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
5720  } else
5721  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5722  if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
5723  Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5724  << 1
5725  << C->getHint()->EvaluateKnownConstInt(Context).toString(
5726  /*Radix=*/10, /*Signed=*/false);
5727  } else
5728  Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5729  }
5730  }
5731 
5733 
5734  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
5735  Clauses, AStmt);
5736  if (!Pair.first && DirName.getName() && !DependentHint)
5737  DSAStack->addCriticalWithHint(Dir, Hint);
5738  return Dir;
5739 }
5740 
5742  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5743  SourceLocation EndLoc,
5744  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5745  if (!AStmt)
5746  return StmtError();
5747 
5748  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5749  // 1.2.2 OpenMP Language Terminology
5750  // Structured block - An executable statement with a single entry at the
5751  // top and a single exit at the bottom.
5752  // The point of exit cannot be a branch out of the structured block.
5753  // longjmp() and throw() must not violate the entry/exit criteria.
5754  CS->getCapturedDecl()->setNothrow();
5755 
5757  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5758  // define the nested loops number.
5759  unsigned NestedLoopCount =
5760  CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
5761  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5762  VarsWithImplicitDSA, B);
5763  if (NestedLoopCount == 0)
5764  return StmtError();
5765 
5766  assert((CurContext->isDependentContext() || B.builtAll()) &&
5767  "omp parallel for loop exprs were not built");
5768 
5769  if (!CurContext->isDependentContext()) {
5770  // Finalize the clauses that need pre-built expressions for CodeGen.
5771  for (auto C : Clauses) {
5772  if (auto LC = dyn_cast<OMPLinearClause>(C))
5773  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5774  B.NumIterations, *this, CurScope,
5775  DSAStack))
5776  return StmtError();
5777  }
5778  }
5779 
5781  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
5782  NestedLoopCount, Clauses, AStmt, B,
5783  DSAStack->isCancelRegion());
5784 }
5785 
5787  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5788  SourceLocation EndLoc,
5789  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5790  if (!AStmt)
5791  return StmtError();
5792 
5793  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5794  // 1.2.2 OpenMP Language Terminology
5795  // Structured block - An executable statement with a single entry at the
5796  // top and a single exit at the bottom.
5797  // The point of exit cannot be a branch out of the structured block.
5798  // longjmp() and throw() must not violate the entry/exit criteria.
5799  CS->getCapturedDecl()->setNothrow();
5800 
5802  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5803  // define the nested loops number.
5804  unsigned NestedLoopCount =
5805  CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
5806  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5807  VarsWithImplicitDSA, B);
5808  if (NestedLoopCount == 0)
5809  return StmtError();
5810 
5811  if (!CurContext->isDependentContext()) {
5812  // Finalize the clauses that need pre-built expressions for CodeGen.
5813  for (auto C : Clauses) {
5814  if (auto LC = dyn_cast<OMPLinearClause>(C))
5815  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5816  B.NumIterations, *this, CurScope,
5817  DSAStack))
5818  return StmtError();
5819  }
5820  }
5821 
5822  if (checkSimdlenSafelenSpecified(*this, Clauses))
5823  return StmtError();
5824 
5827  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5828 }
5829 
5830 StmtResult
5832  Stmt *AStmt, SourceLocation StartLoc,
5833  SourceLocation EndLoc) {
5834  if (!AStmt)
5835  return StmtError();
5836 
5837  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5838  auto BaseStmt = AStmt;
5839  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5840  BaseStmt = CS->getCapturedStmt();
5841  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5842  auto S = C->children();
5843  if (S.begin() == S.end())
5844  return StmtError();
5845  // All associated statements must be '#pragma omp section' except for
5846  // the first one.
5847  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5848  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5849  if (SectionStmt)
5850  Diag(SectionStmt->getLocStart(),
5851  diag::err_omp_parallel_sections_substmt_not_section);
5852  return StmtError();
5853  }
5854  cast<OMPSectionDirective>(SectionStmt)
5855  ->setHasCancel(DSAStack->isCancelRegion());
5856  }
5857  } else {
5858  Diag(AStmt->getLocStart(),
5859  diag::err_omp_parallel_sections_not_compound_stmt);
5860  return StmtError();
5861  }
5862 
5864 
5866  Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
5867 }
5868 
5870  Stmt *AStmt, SourceLocation StartLoc,
5871  SourceLocation EndLoc) {
5872  if (!AStmt)
5873  return StmtError();
5874 
5875  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5876  // 1.2.2 OpenMP Language Terminology
5877  // Structured block - An executable statement with a single entry at the
5878  // top and a single exit at the bottom.
5879  // The point of exit cannot be a branch out of the structured block.
5880  // longjmp() and throw() must not violate the entry/exit criteria.
5881  CS->getCapturedDecl()->setNothrow();
5882 
5884 
5885  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5886  DSAStack->isCancelRegion());
5887 }
5888 
5890  SourceLocation EndLoc) {
5891  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
5892 }
5893 
5895  SourceLocation EndLoc) {
5896  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
5897 }
5898 
5900  SourceLocation EndLoc) {
5901  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
5902 }
5903 
5905  SourceLocation StartLoc,
5906  SourceLocation EndLoc) {
5907  if (!AStmt)
5908  return StmtError();
5909 
5910  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5911 
5913 
5914  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt);
5915 }
5916 
5918  SourceLocation StartLoc,
5919  SourceLocation EndLoc) {
5920  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
5921  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
5922 }
5923 
5925  Stmt *AStmt,
5926  SourceLocation StartLoc,
5927  SourceLocation EndLoc) {
5928  OMPClause *DependFound = nullptr;
5929  OMPClause *DependSourceClause = nullptr;
5930  OMPClause *DependSinkClause = nullptr;
5931  bool ErrorFound = false;
5932  OMPThreadsClause *TC = nullptr;
5933  OMPSIMDClause *SC = nullptr;
5934  for (auto *C : Clauses) {
5935  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
5936  DependFound = C;
5937  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5938  if (DependSourceClause) {
5939  Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5940  << getOpenMPDirectiveName(OMPD_ordered)
5941  << getOpenMPClauseName(OMPC_depend) << 2;
5942  ErrorFound = true;
5943  } else
5944  DependSourceClause = C;
5945  if (DependSinkClause) {
5946  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5947  << 0;
5948  ErrorFound = true;
5949  }
5950  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5951  if (DependSourceClause) {
5952  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5953  << 1;
5954  ErrorFound = true;
5955  }
5956  DependSinkClause = C;
5957  }
5958  } else if (C->getClauseKind() == OMPC_threads)
5959  TC = cast<OMPThreadsClause>(C);
5960  else if (C->getClauseKind() == OMPC_simd)
5961  SC = cast<OMPSIMDClause>(C);
5962  }
5963  if (!ErrorFound && !SC &&
5964  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
5965  // OpenMP [2.8.1,simd Construct, Restrictions]
5966  // An ordered construct with the simd clause is the only OpenMP construct
5967  // that can appear in the simd region.
5968  Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5969  ErrorFound = true;
5970  } else if (DependFound && (TC || SC)) {
5971  Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
5972  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
5973  ErrorFound = true;
5974  } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) {
5975  Diag(DependFound->getLocStart(),
5976  diag::err_omp_ordered_directive_without_param);
5977  ErrorFound = true;
5978  } else if (TC || Clauses.empty()) {
5979  if (auto *Param = DSAStack->getParentOrderedRegionParam()) {
5980  SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
5981  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5982  << (TC != nullptr);
5983  Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5984  ErrorFound = true;
5985  }
5986  }
5987  if ((!AStmt && !DependFound) || ErrorFound)
5988  return StmtError();
5989 
5990  if (AStmt) {
5991  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5992 
5994  }
5995 
5996  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5997 }
5998 
5999 namespace {
6000 /// \brief Helper class for checking expression in 'omp atomic [update]'
6001 /// construct.
6002 class OpenMPAtomicUpdateChecker {
6003  /// \brief Error results for atomic update expressions.
6004  enum ExprAnalysisErrorCode {
6005  /// \brief A statement is not an expression statement.
6006  NotAnExpression,
6007  /// \brief Expression is not builtin binary or unary operation.
6008  NotABinaryOrUnaryExpression,
6009  /// \brief Unary operation is not post-/pre- increment/decrement operation.
6010  NotAnUnaryIncDecExpression,
6011  /// \brief An expression is not of scalar type.
6012  NotAScalarType,
6013  /// \brief A binary operation is not an assignment operation.
6014  NotAnAssignmentOp,
6015  /// \brief RHS part of the binary operation is not a binary expression.
6016  NotABinaryExpression,
6017  /// \brief RHS part is not additive/multiplicative/shift/biwise binary
6018  /// expression.
6019  NotABinaryOperator,
6020  /// \brief RHS binary operation does not have reference to the updated LHS
6021  /// part.
6022  NotAnUpdateExpression,
6023  /// \brief No errors is found.
6024  NoError
6025  };
6026  /// \brief Reference to Sema.
6027  Sema &SemaRef;
6028  /// \brief A location for note diagnostics (when error is found).
6029  SourceLocation NoteLoc;
6030  /// \brief 'x' lvalue part of the source atomic expression.
6031  Expr *X;
6032  /// \brief 'expr' rvalue part of the source atomic expression.
6033  Expr *E;
6034  /// \brief Helper expression of the form
6035  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6036  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6037  Expr *UpdateExpr;
6038  /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
6039  /// important for non-associative operations.
6040  bool IsXLHSInRHSPart;
6041  BinaryOperatorKind Op;
6042  SourceLocation OpLoc;
6043  /// \brief true if the source expression is a postfix unary operation, false
6044  /// if it is a prefix unary operation.
6045  bool IsPostfixUpdate;
6046 
6047 public:
6048  OpenMPAtomicUpdateChecker(Sema &SemaRef)
6049  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
6050  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
6051  /// \brief Check specified statement that it is suitable for 'atomic update'
6052  /// constructs and extract 'x', 'expr' and Operation from the original
6053  /// expression. If DiagId and NoteId == 0, then only check is performed
6054  /// without error notification.
6055  /// \param DiagId Diagnostic which should be emitted if error is found.
6056  /// \param NoteId Diagnostic note for the main error message.
6057  /// \return true if statement is not an update expression, false otherwise.
6058  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
6059  /// \brief Return the 'x' lvalue part of the source atomic expression.
6060  Expr *getX() const { return X; }
6061  /// \brief Return the 'expr' rvalue part of the source atomic expression.
6062  Expr *getExpr() const { return E; }
6063  /// \brief Return the update expression used in calculation of the updated
6064  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6065  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6066  Expr *getUpdateExpr() const { return UpdateExpr; }
6067  /// \brief Return true if 'x' is LHS in RHS part of full update expression,
6068  /// false otherwise.
6069  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
6070 
6071  /// \brief true if the source expression is a postfix unary operation, false
6072  /// if it is a prefix unary operation.
6073  bool isPostfixUpdate() const { return IsPostfixUpdate; }
6074 
6075 private:
6076  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
6077  unsigned NoteId = 0);
6078 };
6079 } // namespace
6080 
6081 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6082  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
6083  ExprAnalysisErrorCode ErrorFound = NoError;
6084  SourceLocation ErrorLoc, NoteLoc;
6085  SourceRange ErrorRange, NoteRange;
6086  // Allowed constructs are:
6087  // x = x binop expr;
6088  // x = expr binop x;
6089  if (AtomicBinOp->getOpcode() == BO_Assign) {
6090  X = AtomicBinOp->getLHS();
6091  if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6092  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
6093  if (AtomicInnerBinOp->isMultiplicativeOp() ||
6094  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6095  AtomicInnerBinOp->isBitwiseOp()) {
6096  Op = AtomicInnerBinOp->getOpcode();
6097  OpLoc = AtomicInnerBinOp->getOperatorLoc();
6098  auto *LHS = AtomicInnerBinOp->getLHS();
6099  auto *RHS = AtomicInnerBinOp->getRHS();
6100  llvm::FoldingSetNodeID XId, LHSId, RHSId;
6101  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
6102  /*Canonical=*/true);
6103  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
6104  /*Canonical=*/true);
6105  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
6106  /*Canonical=*/true);
6107  if (XId == LHSId) {
6108  E = RHS;
6109  IsXLHSInRHSPart = true;
6110  } else if (XId == RHSId) {
6111  E = LHS;
6112  IsXLHSInRHSPart = false;
6113  } else {
6114  ErrorLoc = AtomicInnerBinOp->getExprLoc();
6115  ErrorRange = AtomicInnerBinOp->getSourceRange();
6116  NoteLoc = X->getExprLoc();
6117  NoteRange = X->getSourceRange();
6118  ErrorFound = NotAnUpdateExpression;
6119  }
6120  } else {
6121  ErrorLoc = AtomicInnerBinOp->getExprLoc();
6122  ErrorRange = AtomicInnerBinOp->getSourceRange();
6123  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6124  NoteRange = SourceRange(NoteLoc, NoteLoc);
6125  ErrorFound = NotABinaryOperator;
6126  }
6127  } else {
6128  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
6129  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
6130  ErrorFound = NotABinaryExpression;
6131  }
6132  } else {
6133  ErrorLoc = AtomicBinOp->getExprLoc();
6134  ErrorRange = AtomicBinOp->getSourceRange();
6135  NoteLoc = AtomicBinOp->getOperatorLoc();
6136  NoteRange = SourceRange(NoteLoc, NoteLoc);
6137  ErrorFound = NotAnAssignmentOp;
6138  }
6139  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6140  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6141  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6142  return true;
6143  } else if (SemaRef.CurContext->isDependentContext())
6144  E = X = UpdateExpr = nullptr;
6145  return ErrorFound != NoError;
6146 }
6147 
6148 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
6149  unsigned NoteId) {
6150  ExprAnalysisErrorCode ErrorFound = NoError;
6151  SourceLocation ErrorLoc, NoteLoc;
6152  SourceRange ErrorRange, NoteRange;
6153  // Allowed constructs are:
6154  // x++;
6155  // x--;
6156  // ++x;
6157  // --x;
6158  // x binop= expr;
6159  // x = x binop expr;
6160  // x = expr binop x;
6161  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
6162  AtomicBody = AtomicBody->IgnoreParenImpCasts();
6163  if (AtomicBody->getType()->isScalarType() ||
6164  AtomicBody->isInstantiationDependent()) {
6165  if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6166  AtomicBody->IgnoreParenImpCasts())) {
6167  // Check for Compound Assignment Operation
6169  AtomicCompAssignOp->getOpcode());
6170  OpLoc = AtomicCompAssignOp->getOperatorLoc();
6171  E = AtomicCompAssignOp->getRHS();
6172  X = AtomicCompAssignOp->getLHS();
6173  IsXLHSInRHSPart = true;
6174  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6175  AtomicBody->IgnoreParenImpCasts())) {
6176  // Check for Binary Operation
6177  if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6178  return true;
6179  } else if (auto *AtomicUnaryOp =
6180  dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) {
6181  // Check for Unary Operation
6182  if (AtomicUnaryOp->isIncrementDecrementOp()) {
6183  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6184  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6185  OpLoc = AtomicUnaryOp->getOperatorLoc();
6186  X = AtomicUnaryOp->getSubExpr();
6187  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
6188  IsXLHSInRHSPart = true;
6189  } else {
6190  ErrorFound = NotAnUnaryIncDecExpression;
6191  ErrorLoc = AtomicUnaryOp->getExprLoc();
6192  ErrorRange = AtomicUnaryOp->getSourceRange();
6193  NoteLoc = AtomicUnaryOp->getOperatorLoc();
6194  NoteRange = SourceRange(NoteLoc, NoteLoc);
6195  }
6196  } else if (!AtomicBody->isInstantiationDependent()) {
6197  ErrorFound = NotABinaryOrUnaryExpression;
6198  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6199  NoteRange = ErrorRange = AtomicBody->getSourceRange();
6200  }
6201  } else {
6202  ErrorFound = NotAScalarType;
6203  NoteLoc = ErrorLoc = AtomicBody->getLocStart();
6204  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6205  }
6206  } else {
6207  ErrorFound = NotAnExpression;
6208  NoteLoc = ErrorLoc = S->getLocStart();
6209  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6210  }
6211  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6212  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6213  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6214  return true;
6215  } else if (SemaRef.CurContext->isDependentContext())
6216  E = X = UpdateExpr = nullptr;
6217  if (ErrorFound == NoError && E && X) {
6218  // Build an update expression of form 'OpaqueValueExpr(x) binop
6219  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
6220  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
6221  auto *OVEX = new (SemaRef.getASTContext())
6222  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
6223  auto *OVEExpr = new (SemaRef.getASTContext())
6225  auto Update =
6226  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
6227  IsXLHSInRHSPart ? OVEExpr : OVEX);
6228  if (Update.isInvalid())
6229  return true;
6230  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
6232  if (Update.isInvalid())
6233  return true;
6234  UpdateExpr = Update.get();
6235  }
6236  return ErrorFound != NoError;
6237 }
6238 
6240  Stmt *AStmt,
6241  SourceLocation StartLoc,
6242  SourceLocation EndLoc) {
6243  if (!AStmt)
6244  return StmtError();
6245 
6246  auto CS = cast<CapturedStmt>(AStmt);
6247  // 1.2.2 OpenMP Language Terminology
6248  // Structured block - An executable statement with a single entry at the
6249  // top and a single exit at the bottom.
6250  // The point of exit cannot be a branch out of the structured block.
6251  // longjmp() and throw() must not violate the entry/exit criteria.
6252  OpenMPClauseKind AtomicKind = OMPC_unknown;
6253  SourceLocation AtomicKindLoc;
6254  for (auto *C : Clauses) {
6255  if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
6256  C->getClauseKind() == OMPC_update ||
6257  C->getClauseKind() == OMPC_capture) {
6258  if (AtomicKind != OMPC_unknown) {
6259  Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
6260  << SourceRange(C->getLocStart(), C->getLocEnd());
6261  Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6262  << getOpenMPClauseName(AtomicKind);
6263  } else {
6264  AtomicKind = C->getClauseKind();
6265  AtomicKindLoc = C->getLocStart();
6266  }
6267  }
6268  }
6269 
6270  auto Body = CS->getCapturedStmt();
6271  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6272  Body = EWC->getSubExpr();
6273 
6274  Expr *X = nullptr;
6275  Expr *V = nullptr;
6276  Expr *E = nullptr;
6277  Expr *UE = nullptr;
6278  bool IsXLHSInRHSPart = false;
6279  bool IsPostfixUpdate = false;
6280  // OpenMP [2.12.6, atomic Construct]
6281  // In the next expressions:
6282  // * x and v (as applicable) are both l-value expressions with scalar type.
6283  // * During the execution of an atomic region, multiple syntactic
6284  // occurrences of x must designate the same storage location.
6285  // * Neither of v and expr (as applicable) may access the storage location
6286  // designated by x.
6287  // * Neither of x and expr (as applicable) may access the storage location
6288  // designated by v.
6289  // * expr is an expression with scalar type.
6290  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
6291  // * binop, binop=, ++, and -- are not overloaded operators.
6292  // * The expression x binop expr must be numerically equivalent to x binop
6293  // (expr). This requirement is satisfied if the operators in expr have
6294  // precedence greater than binop, or by using parentheses around expr or
6295  // subexpressions of expr.
6296  // * The expression expr binop x must be numerically equivalent to (expr)
6297  // binop x. This requirement is satisfied if the operators in expr have
6298  // precedence equal to or greater than binop, or by using parentheses around
6299  // expr or subexpressions of expr.
6300  // * For forms that allow multiple occurrences of x, the number of times
6301  // that x is evaluated is unspecified.
6302  if (AtomicKind == OMPC_read) {
6303  enum {
6304  NotAnExpression,
6305  NotAnAssignmentOp,
6306  NotAScalarType,
6307  NotAnLValue,
6308  NoError
6309  } ErrorFound = NoError;
6310  SourceLocation ErrorLoc, NoteLoc;
6311  SourceRange ErrorRange, NoteRange;
6312  // If clause is read:
6313  // v = x;
6314  if (auto AtomicBody = dyn_cast<Expr>(Body)) {
6315  auto AtomicBinOp =
6316  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6317  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6318  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6319  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
6320  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6321  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
6322  if (!X->isLValue() || !V->isLValue()) {
6323  auto NotLValueExpr = X->isLValue() ? V : X;
6324  ErrorFound = NotAnLValue;
6325  ErrorLoc = AtomicBinOp->getExprLoc();
6326  ErrorRange = AtomicBinOp->getSourceRange();
6327  NoteLoc = NotLValueExpr->getExprLoc();
6328  NoteRange = NotLValueExpr->getSourceRange();
6329  }
6330  } else if (!X->isInstantiationDependent() ||
6331  !V->isInstantiationDependent()) {
6332  auto NotScalarExpr =
6334  ? V
6335  : X;
6336  ErrorFound = NotAScalarType;
6337  ErrorLoc = AtomicBinOp->getExprLoc();
6338  ErrorRange = AtomicBinOp->getSourceRange();
6339  NoteLoc = NotScalarExpr->getExprLoc();
6340  NoteRange = NotScalarExpr->getSourceRange();
6341  }
6342  } else if (!AtomicBody->isInstantiationDependent()) {
6343  ErrorFound = NotAnAssignmentOp;
6344  ErrorLoc = AtomicBody->getExprLoc();
6345  ErrorRange = AtomicBody->getSourceRange();
6346  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6347  : AtomicBody->getExprLoc();
6348  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6349  : AtomicBody->getSourceRange();
6350  }
6351  } else {
6352  ErrorFound = NotAnExpression;
6353  NoteLoc = ErrorLoc = Body->getLocStart();
6354  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6355  }
6356  if (ErrorFound != NoError) {
6357  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6358  << ErrorRange;
6359  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6360  << NoteRange;
6361  return StmtError();
6362  } else if (CurContext->isDependentContext())
6363  V = X = nullptr;
6364  } else if (AtomicKind == OMPC_write) {
6365  enum {
6366  NotAnExpression,
6367  NotAnAssignmentOp,
6368  NotAScalarType,
6369  NotAnLValue,
6370  NoError
6371  } ErrorFound = NoError;
6372  SourceLocation ErrorLoc, NoteLoc;
6373  SourceRange ErrorRange, NoteRange;
6374  // If clause is write:
6375  // x = expr;
6376  if (auto AtomicBody = dyn_cast<Expr>(Body)) {
6377  auto AtomicBinOp =
6378  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6379  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6380  X = AtomicBinOp->getLHS();
6381  E = AtomicBinOp->getRHS();
6382  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6383  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6384  if (!X->isLValue()) {
6385  ErrorFound = NotAnLValue;
6386  ErrorLoc = AtomicBinOp->getExprLoc();
6387  ErrorRange = AtomicBinOp->getSourceRange();
6388  NoteLoc = X->getExprLoc();
6389  NoteRange = X->getSourceRange();
6390  }
6391  } else if (!X->isInstantiationDependent() ||
6392  !E->isInstantiationDependent()) {
6393  auto NotScalarExpr =
6395  ? E
6396  : X;
6397  ErrorFound = NotAScalarType;
6398  ErrorLoc = AtomicBinOp->getExprLoc();
6399  ErrorRange = AtomicBinOp->getSourceRange();
6400  NoteLoc = NotScalarExpr->getExprLoc();
6401  NoteRange = NotScalarExpr->getSourceRange();
6402  }
6403  } else if (!AtomicBody->isInstantiationDependent()) {
6404  ErrorFound = NotAnAssignmentOp;
6405  ErrorLoc = AtomicBody->getExprLoc();
6406  ErrorRange = AtomicBody->getSourceRange();
6407  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6408  : AtomicBody->getExprLoc();
6409  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6410  : AtomicBody->getSourceRange();
6411  }
6412  } else {
6413  ErrorFound = NotAnExpression;
6414  NoteLoc = ErrorLoc = Body->getLocStart();
6415  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6416  }
6417  if (ErrorFound != NoError) {
6418  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6419  << ErrorRange;
6420  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6421  << NoteRange;
6422  return StmtError();
6423  } else if (CurContext->isDependentContext())
6424  E = X = nullptr;
6425  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6426  // If clause is update:
6427  // x++;
6428  // x--;
6429  // ++x;
6430  // --x;
6431  // x binop= expr;
6432  // x = x binop expr;
6433  // x = expr binop x;
6434  OpenMPAtomicUpdateChecker Checker(*this);
6435  if (Checker.checkStatement(
6436  Body, (AtomicKind == OMPC_update)
6437  ? diag::err_omp_atomic_update_not_expression_statement
6438  : diag::err_omp_atomic_not_expression_statement,
6439  diag::note_omp_atomic_update))
6440  return StmtError();
6441  if (!CurContext->isDependentContext()) {
6442  E = Checker.getExpr();
6443  X = Checker.getX();
6444  UE = Checker.getUpdateExpr();
6445  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6446  }
6447  } else if (AtomicKind == OMPC_capture) {
6448  enum {
6449  NotAnAssignmentOp,
6450  NotACompoundStatement,
6451  NotTwoSubstatements,
6452  NotASpecificExpression,
6453  NoError
6454  } ErrorFound = NoError;
6455  SourceLocation ErrorLoc, NoteLoc;
6456  SourceRange ErrorRange, NoteRange;
6457  if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6458  // If clause is a capture:
6459  // v = x++;
6460  // v = x--;
6461  // v = ++x;
6462  // v = --x;
6463  // v = x binop= expr;
6464  // v = x = x binop expr;
6465  // v = x = expr binop x;
6466  auto *AtomicBinOp =
6467  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6468  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6469  V = AtomicBinOp->getLHS();
6470  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6471  OpenMPAtomicUpdateChecker Checker(*this);
6472  if (Checker.checkStatement(
6473  Body, diag::err_omp_atomic_capture_not_expression_statement,
6474  diag::note_omp_atomic_update))
6475  return StmtError();
6476  E = Checker.getExpr();
6477  X = Checker.getX();
6478  UE = Checker.getUpdateExpr();
6479  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6480  IsPostfixUpdate = Checker.isPostfixUpdate();
6481  } else if (!AtomicBody->isInstantiationDependent()) {
6482  ErrorLoc = AtomicBody->getExprLoc();
6483  ErrorRange = AtomicBody->getSourceRange();
6484  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6485  : AtomicBody->getExprLoc();
6486  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6487  : AtomicBody->getSourceRange();
6488  ErrorFound = NotAnAssignmentOp;
6489  }
6490  if (ErrorFound != NoError) {
6491  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6492  << ErrorRange;
6493  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6494  return StmtError();
6495  } else if (CurContext->isDependentContext()) {
6496  UE = V = E = X = nullptr;
6497  }
6498  } else {
6499  // If clause is a capture:
6500  // { v = x; x = expr; }
6501  // { v = x; x++; }
6502  // { v = x; x--; }
6503  // { v = x; ++x; }
6504  // { v = x; --x; }
6505  // { v = x; x binop= expr; }
6506  // { v = x; x = x binop expr; }
6507  // { v = x; x = expr binop x; }
6508  // { x++; v = x; }
6509  // { x--; v = x; }
6510  // { ++x; v = x; }
6511  // { --x; v = x; }
6512  // { x binop= expr; v = x; }
6513  // { x = x binop expr; v = x; }
6514  // { x = expr binop x; v = x; }
6515  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6516  // Check that this is { expr1; expr2; }
6517  if (CS->size() == 2) {
6518  auto *First = CS->body_front();
6519  auto *Second = CS->body_back();
6520  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6521  First = EWC->getSubExpr()->IgnoreParenImpCasts();
6522  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6523  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6524  // Need to find what subexpression is 'v' and what is 'x'.
6525  OpenMPAtomicUpdateChecker Checker(*this);
6526  bool IsUpdateExprFound = !Checker.checkStatement(Second);
6527  BinaryOperator *BinOp = nullptr;
6528  if (IsUpdateExprFound) {
6529  BinOp = dyn_cast<BinaryOperator>(First);
6530  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6531  }
6532  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6533  // { v = x; x++; }
6534  // { v = x; x--; }
6535  // { v = x; ++x; }
6536  // { v = x; --x; }
6537  // { v = x; x binop= expr; }
6538  // { v = x; x = x binop expr; }
6539  // { v = x; x = expr binop x; }
6540  // Check that the first expression has form v = x.
6541  auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6542  llvm::FoldingSetNodeID XId, PossibleXId;
6543  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6544  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6545  IsUpdateExprFound = XId == PossibleXId;
6546  if (IsUpdateExprFound) {
6547  V = BinOp->getLHS();
6548  X = Checker.getX();
6549  E = Checker.getExpr();
6550  UE = Checker.getUpdateExpr();
6551  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6552  IsPostfixUpdate = true;
6553  }
6554  }
6555  if (!IsUpdateExprFound) {
6556  IsUpdateExprFound = !Checker.checkStatement(First);
6557  BinOp = nullptr;
6558  if (IsUpdateExprFound) {
6559  BinOp = dyn_cast<BinaryOperator>(Second);
6560  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6561  }
6562  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6563  // { x++; v = x; }
6564  // { x--; v = x; }
6565  // { ++x; v = x; }
6566  // { --x; v = x; }
6567  // { x binop= expr; v = x; }
6568  // { x = x binop expr; v = x; }
6569  // { x = expr binop x; v = x; }
6570  // Check that the second expression has form v = x.
6571  auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6572  llvm::FoldingSetNodeID XId, PossibleXId;
6573  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6574  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6575  IsUpdateExprFound = XId == PossibleXId;
6576  if (IsUpdateExprFound) {
6577  V = BinOp->getLHS();
6578  X = Checker.getX();
6579  E = Checker.getExpr();
6580  UE = Checker.getUpdateExpr();
6581  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6582  IsPostfixUpdate = false;
6583  }
6584  }
6585  }
6586  if (!IsUpdateExprFound) {
6587  // { v = x; x = expr; }
6588  auto *FirstExpr = dyn_cast<Expr>(First);
6589  auto *SecondExpr = dyn_cast<Expr>(Second);
6590  if (!FirstExpr || !SecondExpr ||
6591  !(FirstExpr->isInstantiationDependent() ||
6592  SecondExpr->isInstantiationDependent())) {
6593  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6594  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6595  ErrorFound = NotAnAssignmentOp;
6596  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6597  : First->getLocStart();
6598  NoteRange = ErrorRange = FirstBinOp
6599  ? FirstBinOp->getSourceRange()
6600  : SourceRange(ErrorLoc, ErrorLoc);
6601  } else {
6602  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6603  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6604  ErrorFound = NotAnAssignmentOp;
6605  NoteLoc = ErrorLoc = SecondBinOp
6606  ? SecondBinOp->getOperatorLoc()
6607  : Second->getLocStart();
6608  NoteRange = ErrorRange =
6609  SecondBinOp ? SecondBinOp->getSourceRange()
6610  : SourceRange(ErrorLoc, ErrorLoc);
6611  } else {
6612  auto *PossibleXRHSInFirst =
6613  FirstBinOp->getRHS()->IgnoreParenImpCasts();
6614  auto *PossibleXLHSInSecond =
6615  SecondBinOp->getLHS()->IgnoreParenImpCasts();
6616  llvm::FoldingSetNodeID X1Id, X2Id;
6617  PossibleXRHSInFirst->Profile(X1Id, Context,
6618  /*Canonical=*/true);
6619  PossibleXLHSInSecond->Profile(X2Id, Context,
6620  /*Canonical=*/true);
6621  IsUpdateExprFound = X1Id == X2Id;
6622  if (IsUpdateExprFound) {
6623  V = FirstBinOp->getLHS();
6624  X = SecondBinOp->getLHS();
6625  E = SecondBinOp->getRHS();
6626  UE = nullptr;
6627  IsXLHSInRHSPart = false;
6628  IsPostfixUpdate = true;
6629  } else {
6630  ErrorFound = NotASpecificExpression;
6631  ErrorLoc = FirstBinOp->getExprLoc();
6632  ErrorRange = FirstBinOp->getSourceRange();
6633  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6634  NoteRange = SecondBinOp->getRHS()->getSourceRange();
6635  }
6636  }
6637  }
6638  }
6639  }
6640  } else {
6641  NoteLoc = ErrorLoc = Body->getLocStart();
6642  NoteRange = ErrorRange =
6643  SourceRange(Body->getLocStart(), Body->getLocStart());
6644  ErrorFound = NotTwoSubstatements;
6645  }
6646  } else {
6647  NoteLoc = ErrorLoc = Body->getLocStart();
6648  NoteRange = ErrorRange =
6649  SourceRange(Body->getLocStart(), Body->getLocStart());
6650  ErrorFound = NotACompoundStatement;
6651  }
6652  if (ErrorFound != NoError) {
6653  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6654  << ErrorRange;
6655  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6656  return StmtError();
6657  } else if (CurContext->isDependentContext()) {
6658  UE = V = E = X = nullptr;
6659  }
6660  }
6661  }
6662 
6664 
6665  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6666  X, V, E, UE, IsXLHSInRHSPart,
6667  IsPostfixUpdate);
6668 }
6669 
6671  Stmt *AStmt,
6672  SourceLocation StartLoc,
6673  SourceLocation EndLoc) {
6674  if (!AStmt)
6675  return StmtError();
6676 
6677  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6678  // 1.2.2 OpenMP Language Terminology
6679  // Structured block - An executable statement with a single entry at the
6680  // top and a single exit at the bottom.
6681  // The point of exit cannot be a branch out of the structured block.
6682  // longjmp() and throw() must not violate the entry/exit criteria.
6683  CS->getCapturedDecl()->setNothrow();
6684 
6685  // OpenMP [2.16, Nesting of Regions]
6686  // If specified, a teams construct must be contained within a target
6687  // construct. That target construct must contain no statements or directives
6688  // outside of the teams construct.
6689  if (DSAStack->hasInnerTeamsRegion()) {
6690  auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true);
6691  bool OMPTeamsFound = true;
6692  if (auto *CS = dyn_cast<CompoundStmt>(S)) {
6693  auto I = CS->body_begin();
6694  while (I != CS->body_end()) {
6695  auto OED = dyn_cast<OMPExecutableDirective>(*I);
6696  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
6697  OMPTeamsFound = false;
6698  break;
6699  }
6700  ++I;
6701  }
6702  assert(I != CS->body_end() && "Not found statement");
6703  S = *I;
6704  } else {
6705  auto *OED = dyn_cast<OMPExecutableDirective>(S);
6706  OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
6707  }
6708  if (!OMPTeamsFound) {
6709  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6710  Diag(DSAStack->getInnerTeamsRegionLoc(),
6711  diag::note_omp_nested_teams_construct_here);
6712  Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
6713  << isa<OMPExecutableDirective>(S);
6714  return StmtError();
6715  }
6716  }
6717 
6719 
6720  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6721 }
6722 
6723 StmtResult
6725  Stmt *AStmt, SourceLocation StartLoc,
6726  SourceLocation EndLoc) {
6727  if (!AStmt)
6728  return StmtError();
6729 
6730  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6731  // 1.2.2 OpenMP Language Terminology
6732  // Structured block - An executable statement with a single entry at the
6733  // top and a single exit at the bottom.
6734  // The point of exit cannot be a branch out of the structured block.
6735  // longjmp() and throw() must not violate the entry/exit criteria.
6736  CS->getCapturedDecl()->setNothrow();
6737 
6739 
6740  return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6741  AStmt);
6742 }
6743 
6745  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6746  SourceLocation EndLoc,
6747  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6748  if (!AStmt)
6749  return StmtError();
6750 
6751  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6752  // 1.2.2 OpenMP Language Terminology
6753  // Structured block - An executable statement with a single entry at the
6754  // top and a single exit at the bottom.
6755  // The point of exit cannot be a branch out of the structured block.
6756  // longjmp() and throw() must not violate the entry/exit criteria.
6757  CS->getCapturedDecl()->setNothrow();
6758 
6760  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6761  // define the nested loops number.
6762  unsigned NestedLoopCount =
6763  CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
6764  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6765  VarsWithImplicitDSA, B);
6766  if (NestedLoopCount == 0)
6767  return StmtError();
6768 
6769  assert((CurContext->isDependentContext() || B.builtAll()) &&
6770  "omp target parallel for loop exprs were not built");
6771 
6772  if (!CurContext->isDependentContext()) {
6773  // Finalize the clauses that need pre-built expressions for CodeGen.
6774  for (auto C : Clauses) {
6775  if (auto LC = dyn_cast<OMPLinearClause>(C))
6776  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6777  B.NumIterations, *this, CurScope,
6778  DSAStack))
6779  return StmtError();
6780  }
6781  }
6782 
6784  return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
6785  NestedLoopCount, Clauses, AStmt,
6786  B, DSAStack->isCancelRegion());
6787 }
6788 
6789 /// \brief Check for existence of a map clause in the list of clauses.
6790 static bool HasMapClause(ArrayRef<OMPClause *> Clauses) {
6791  for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
6792  I != E; ++I) {
6793  if (*I != nullptr && (*I)->getClauseKind() == OMPC_map) {
6794  return true;
6795  }
6796  }
6797 
6798  return false;
6799 }
6800 
6802  Stmt *AStmt,
6803  SourceLocation StartLoc,
6804  SourceLocation EndLoc) {
6805  if (!AStmt)
6806  return StmtError();
6807 
6808  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6809 
6810  // OpenMP [2.10.1, Restrictions, p. 97]
6811  // At least one map clause must appear on the directive.
6812  if (!HasMapClause(Clauses)) {
6813  Diag(StartLoc, diag::err_omp_no_map_for_directive) <<
6814  getOpenMPDirectiveName(OMPD_target_data);
6815  return StmtError();
6816  }
6817 
6819 
6820  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6821  AStmt);
6822 }
6823 
6824 StmtResult
6826  SourceLocation StartLoc,
6827  SourceLocation EndLoc) {
6828  // OpenMP [2.10.2, Restrictions, p. 99]
6829  // At least one map clause must appear on the directive.
6830  if (!HasMapClause(Clauses)) {
6831  Diag(StartLoc, diag::err_omp_no_map_for_directive)
6832  << getOpenMPDirectiveName(OMPD_target_enter_data);
6833  return StmtError();
6834  }
6835 
6836  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc,
6837  Clauses);
6838 }
6839 
6840 StmtResult
6842  SourceLocation StartLoc,
6843  SourceLocation EndLoc) {
6844  // OpenMP [2.10.3, Restrictions, p. 102]
6845  // At least one map clause must appear on the directive.
6846  if (!HasMapClause(Clauses)) {
6847  Diag(StartLoc, diag::err_omp_no_map_for_directive)
6848  << getOpenMPDirectiveName(OMPD_target_exit_data);
6849  return StmtError();
6850  }
6851 
6852  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses);
6853 }
6854 
6856  SourceLocation StartLoc,
6857  SourceLocation EndLoc) {
6858  bool seenMotionClause = false;
6859  for (auto *C : Clauses) {
6860  if (C->getClauseKind() == OMPC_to || C->getClauseKind() == OMPC_from)
6861  seenMotionClause = true;
6862  }
6863  if (!seenMotionClause) {
6864  Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6865  return StmtError();
6866  }
6867  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses);
6868 }
6869 
6871  Stmt *AStmt, SourceLocation StartLoc,
6872  SourceLocation EndLoc) {
6873  if (!AStmt)
6874  return StmtError();
6875 
6876  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6877  // 1.2.2 OpenMP Language Terminology
6878  // Structured block - An executable statement with a single entry at the
6879  // top and a single exit at the bottom.
6880  // The point of exit cannot be a branch out of the structured block.
6881  // longjmp() and throw() must not violate the entry/exit criteria.
6882  CS->getCapturedDecl()->setNothrow();
6883 
6885 
6886  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6887 }
6888 
6889 StmtResult
6891  SourceLocation EndLoc,
6892  OpenMPDirectiveKind CancelRegion) {
6893  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
6894  CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
6895  Diag(StartLoc, diag::err_omp_wrong_cancel_region)
6896  << getOpenMPDirectiveName(CancelRegion);
6897  return StmtError();
6898  }
6899  if (DSAStack->isParentNowaitRegion()) {
6900  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6901  return StmtError();
6902  }
6903  if (DSAStack->isParentOrderedRegion()) {
6904  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6905  return StmtError();
6906  }
6907  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
6908  CancelRegion);
6909 }
6910 
6912  SourceLocation StartLoc,
6913  SourceLocation EndLoc,
6914  OpenMPDirectiveKind CancelRegion) {
6915  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
6916  CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
6917  Diag(StartLoc, diag::err_omp_wrong_cancel_region)
6918  << getOpenMPDirectiveName(CancelRegion);
6919  return StmtError();
6920  }
6921  if (DSAStack->isParentNowaitRegion()) {
6922  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6923  return StmtError();
6924  }
6925  if (DSAStack->isParentOrderedRegion()) {
6926  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6927  return StmtError();
6928  }
6929  DSAStack->setParentCancelRegion(/*Cancel=*/true);
6930  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6931  CancelRegion);
6932 }
6933 
6935  ArrayRef<OMPClause *> Clauses) {
6936  OMPClause *PrevClause = nullptr;
6937  bool ErrorFound = false;
6938  for (auto *C : Clauses) {
6939  if (C->getClauseKind() == OMPC_grainsize ||
6940  C->getClauseKind() == OMPC_num_tasks) {
6941  if (!PrevClause)
6942  PrevClause = C;
6943  else if (PrevClause->getClauseKind() != C->getClauseKind()) {
6944  S.Diag(C->getLocStart(),
6945  diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6946  << getOpenMPClauseName(C->getClauseKind())
6947  << getOpenMPClauseName(PrevClause->getClauseKind());
6948  S.Diag(PrevClause->getLocStart(),
6949  diag::note_omp_previous_grainsize_num_tasks)
6950  << getOpenMPClauseName(PrevClause->getClauseKind());
6951  ErrorFound = true;
6952  }
6953  }
6954  }
6955  return ErrorFound;
6956 }
6957 
6959  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6960  SourceLocation EndLoc,
6961  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6962  if (!AStmt)
6963  return StmtError();
6964 
6965  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6967  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6968  // define the nested loops number.
6969  unsigned NestedLoopCount =
6970  CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
6971  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
6972  VarsWithImplicitDSA, B);
6973  if (NestedLoopCount == 0)
6974  return StmtError();
6975 
6976  assert((CurContext->isDependentContext() || B.builtAll()) &&
6977  "omp for loop exprs were not built");
6978 
6979  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6980  // The grainsize clause and num_tasks clause are mutually exclusive and may
6981  // not appear on the same taskloop directive.
6982  if (checkGrainsizeNumTasksClauses(*this, Clauses))
6983  return StmtError();
6984 
6986  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
6987  NestedLoopCount, Clauses, AStmt, B);
6988 }
6989 
6991  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6992  SourceLocation EndLoc,
6993  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6994  if (!AStmt)
6995  return StmtError();
6996 
6997  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6999  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7000  // define the nested loops number.
7001  unsigned NestedLoopCount =
7002  CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
7003  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7004  VarsWithImplicitDSA, B);
7005  if (NestedLoopCount == 0)
7006  return StmtError();
7007 
7008  assert((CurContext->isDependentContext() || B.builtAll()) &&
7009  "omp for loop exprs were not built");
7010 
7011  if (!CurContext->isDependentContext()) {
7012  // Finalize the clauses that need pre-built expressions for CodeGen.
7013  for (auto C : Clauses) {
7014  if (auto LC = dyn_cast<OMPLinearClause>(C))
7015  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7016  B.NumIterations, *this, CurScope,
7017  DSAStack))
7018  return StmtError();
7019  }
7020  }
7021 
7022  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7023  // The grainsize clause and num_tasks clause are mutually exclusive and may
7024  // not appear on the same taskloop directive.
7025  if (checkGrainsizeNumTasksClauses(*this, Clauses))
7026  return StmtError();
7027 
7029  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
7030  NestedLoopCount, Clauses, AStmt, B);
7031 }
7032 
7034  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7035  SourceLocation EndLoc,
7036  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7037  if (!AStmt)
7038  return StmtError();
7039 
7040  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7042  // In presence of clause 'collapse' with number of loops, it will
7043  // define the nested loops number.
7044  unsigned NestedLoopCount =
7045  CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
7046  nullptr /*ordered not a clause on distribute*/, AStmt,
7047  *this, *DSAStack, VarsWithImplicitDSA, B);
7048  if (NestedLoopCount == 0)
7049  return StmtError();
7050 
7051  assert((CurContext->isDependentContext() || B.builtAll()) &&
7052  "omp for loop exprs were not built");
7053 
7055  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
7056  NestedLoopCount, Clauses, AStmt, B);
7057 }
7058 
7060  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7061  SourceLocation EndLoc,
7062  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7063  if (!AStmt)
7064  return StmtError();
7065 
7066  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7067  // 1.2.2 OpenMP Language Terminology
7068  // Structured block - An executable statement with a single entry at the
7069  // top and a single exit at the bottom.
7070  // The point of exit cannot be a branch out of the structured block.
7071  // longjmp() and throw() must not violate the entry/exit criteria.
7072  CS->getCapturedDecl()->setNothrow();
7073 
7075  // In presence of clause 'collapse' with number of loops, it will
7076  // define the nested loops number.
7077  unsigned NestedLoopCount = CheckOpenMPLoop(
7078  OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7079  nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
7080  VarsWithImplicitDSA, B);
7081  if (NestedLoopCount == 0)
7082  return StmtError();
7083 
7084  assert((CurContext->isDependentContext() || B.builtAll()) &&
7085  "omp for loop exprs were not built");
7086 
7089  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7090 }
7091 
7093  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7094  SourceLocation EndLoc,
7095  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7096  if (!AStmt)
7097  return StmtError();
7098 
7099  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7100  // 1.2.2 OpenMP Language Terminology
7101  // Structured block - An executable statement with a single entry at the
7102  // top and a single exit at the bottom.
7103  // The point of exit cannot be a branch out of the structured block.
7104  // longjmp() and throw() must not violate the entry/exit criteria.
7105  CS->getCapturedDecl()->setNothrow();
7106 
7108  // In presence of clause 'collapse' with number of loops, it will
7109  // define the nested loops number.
7110  unsigned NestedLoopCount = CheckOpenMPLoop(
7111  OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7112  nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
7113  VarsWithImplicitDSA, B);
7114  if (NestedLoopCount == 0)
7115  return StmtError();
7116 
7117  assert((CurContext->isDependentContext() || B.builtAll()) &&
7118  "omp for loop exprs were not built");
7119 
7120  if (checkSimdlenSafelenSpecified(*this, Clauses))
7121  return StmtError();
7122 
7125  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7126 }
7127 
7129  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7130  SourceLocation EndLoc,
7131  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7132  if (!AStmt)
7133  return StmtError();
7134 
7135  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7136  // 1.2.2 OpenMP Language Terminology
7137  // Structured block - An executable statement with a single entry at the
7138  // top and a single exit at the bottom.
7139  // The point of exit cannot be a branch out of the structured block.
7140  // longjmp() and throw() must not violate the entry/exit criteria.
7141  CS->getCapturedDecl()->setNothrow();
7142 
7144  // In presence of clause 'collapse' with number of loops, it will
7145  // define the nested loops number.
7146  unsigned NestedLoopCount =
7147  CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
7148  nullptr /*ordered not a clause on distribute*/, AStmt,
7149  *this, *DSAStack, VarsWithImplicitDSA, B);
7150  if (NestedLoopCount == 0)
7151  return StmtError();
7152 
7153  assert((CurContext->isDependentContext() || B.builtAll()) &&
7154  "omp for loop exprs were not built");
7155 
7156  if (checkSimdlenSafelenSpecified(*this, Clauses))
7157  return StmtError();
7158 
7160  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
7161  NestedLoopCount, Clauses, AStmt, B);
7162 }
7163 
7165  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7166  SourceLocation EndLoc,
7167  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7168  if (!AStmt)
7169  return StmtError();
7170 
7171  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7172  // 1.2.2 OpenMP Language Terminology
7173  // Structured block - An executable statement with a single entry at the
7174  // top and a single exit at the bottom.
7175  // The point of exit cannot be a branch out of the structured block.
7176  // longjmp() and throw() must not violate the entry/exit criteria.
7177  CS->getCapturedDecl()->setNothrow();
7178 
7180  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7181  // define the nested loops number.
7182  unsigned NestedLoopCount = CheckOpenMPLoop(
7183  OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
7184  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
7185  VarsWithImplicitDSA, B);
7186  if (NestedLoopCount == 0)
7187  return StmtError();
7188 
7189  assert((CurContext->isDependentContext() || B.builtAll()) &&
7190  "omp target parallel for simd loop exprs were not built");
7191 
7192  if (!CurContext->isDependentContext()) {
7193  // Finalize the clauses that need pre-built expressions for CodeGen.
7194  for (auto C : Clauses) {
7195  if (auto LC = dyn_cast<OMPLinearClause>(C))
7196  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7197  B.NumIterations, *this, CurScope,
7198  DSAStack))
7199  return StmtError();
7200  }
7201  }
7202  if (checkSimdlenSafelenSpecified(*this, Clauses))
7203  return StmtError();
7204 
7207  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7208 }
7209 
7211  SourceLocation StartLoc,
7212  SourceLocation LParenLoc,
7213  SourceLocation EndLoc) {
7214  OMPClause *Res = nullptr;
7215  switch (Kind) {
7216  case OMPC_final:
7217  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
7218  break;
7219  case OMPC_num_threads:
7220  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
7221  break;
7222  case OMPC_safelen:
7223  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
7224  break;
7225  case OMPC_simdlen:
7226  Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
7227  break;
7228  case OMPC_collapse:
7229  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
7230  break;
7231  case OMPC_ordered:
7232  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
7233  break;
7234  case OMPC_device:
7235  Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
7236  break;
7237  case OMPC_num_teams:
7238  Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
7239  break;
7240  case OMPC_thread_limit:
7241  Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
7242  break;
7243  case OMPC_priority:
7244  Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
7245  break;
7246  case OMPC_grainsize:
7247  Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
7248  break;
7249  case OMPC_num_tasks:
7250  Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
7251  break;
7252  case OMPC_hint:
7253  Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
7254  break;
7255  case OMPC_if:
7256  case OMPC_default:
7257  case OMPC_proc_bind:
7258  case OMPC_schedule:
7259  case OMPC_private:
7260  case OMPC_firstprivate:
7261  case OMPC_lastprivate:
7262  case OMPC_shared:
7263  case OMPC_reduction:
7264  case OMPC_linear:
7265  case OMPC_aligned:
7266  case OMPC_copyin:
7267  case OMPC_copyprivate:
7268  case OMPC_nowait:
7269  case OMPC_untied:
7270  case OMPC_mergeable:
7271  case OMPC_threadprivate:
7272  case OMPC_flush:
7273  case OMPC_read:
7274  case OMPC_write:
7275  case OMPC_update:
7276  case OMPC_capture:
7277  case OMPC_seq_cst:
7278  case OMPC_depend:
7279  case OMPC_threads:
7280  case OMPC_simd:
7281  case OMPC_map:
7282  case OMPC_nogroup:
7283  case OMPC_dist_schedule:
7284  case OMPC_defaultmap:
7285  case OMPC_unknown:
7286  case OMPC_uniform:
7287  case OMPC_to:
7288  case OMPC_from:
7289  case OMPC_use_device_ptr:
7290  case OMPC_is_device_ptr:
7291  llvm_unreachable("Clause is not allowed.");
7292  }
7293  return Res;
7294 }
7295 
7297  Expr *Condition, SourceLocation StartLoc,
7298  SourceLocation LParenLoc,
7299  SourceLocation NameModifierLoc,
7301  SourceLocation EndLoc) {
7302  Expr *ValExpr = Condition;
7303  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
7304  !Condition->isInstantiationDependent() &&
7305  !Condition->containsUnexpandedParameterPack()) {
7306  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
7307  if (Val.isInvalid())
7308  return nullptr;
7309 
7310  ValExpr = MakeFullExpr(Val.get()).get();
7311  }
7312 
7313  return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,
7314  NameModifierLoc, ColonLoc, EndLoc);
7315 }
7316 
7318  SourceLocation StartLoc,
7319  SourceLocation LParenLoc,
7320  SourceLocation EndLoc) {
7321  Expr *ValExpr = Condition;
7322  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
7323  !Condition->isInstantiationDependent() &&
7324  !Condition->containsUnexpandedParameterPack()) {
7325  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
7326  if (Val.isInvalid())
7327  return nullptr;
7328 
7329  ValExpr = MakeFullExpr(Val.get()).get();
7330  }
7331 
7332  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
7333 }
7335  Expr *Op) {
7336  if (!Op)
7337  return ExprError();
7338 
7339  class IntConvertDiagnoser : public ICEConvertDiagnoser {
7340  public:
7341  IntConvertDiagnoser()
7342  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
7343  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
7344  QualType T) override {
7345  return S.Diag(Loc, diag::err_omp_not_integral) << T;
7346  }
7347  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
7348  QualType T) override {
7349  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
7350  }
7351  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
7352  QualType T,
7353  QualType ConvTy) override {
7354  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
7355  }
7356  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
7357  QualType ConvTy) override {
7358  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
7359  << ConvTy->isEnumeralType() << ConvTy;
7360  }
7361  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
7362  QualType T) override {
7363  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
7364  }
7365  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
7366  QualType ConvTy) override {
7367  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
7368  << ConvTy->isEnumeralType() << ConvTy;
7369  }
7370  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
7371  QualType) override {
7372  llvm_unreachable("conversion functions are permitted");
7373  }
7374  } ConvertDiagnoser;
7375  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
7376 }
7377 
7378 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
7379  OpenMPClauseKind CKind,
7380  bool StrictlyPositive) {
7381  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
7382  !ValExpr->isInstantiationDependent()) {
7383  SourceLocation Loc = ValExpr->getExprLoc();
7384  ExprResult Value =
7385  SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
7386  if (Value.isInvalid())
7387  return false;
7388 
7389  ValExpr = Value.get();
7390  // The expression must evaluate to a non-negative integer value.
7391  llvm::APSInt Result;
7392  if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
7393  Result.isSigned() &&
7394  !((!StrictlyPositive && Result.isNonNegative()) ||
7395  (StrictlyPositive && Result.isStrictlyPositive()))) {
7396  SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
7397  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
7398  << ValExpr->getSourceRange();
7399  return false;
7400  }
7401  }
7402  return true;
7403 }
7404 
7406  SourceLocation StartLoc,
7407  SourceLocation LParenLoc,
7408  SourceLocation EndLoc) {
7409  Expr *ValExpr = NumThreads;
7410 
7411  // OpenMP [2.5, Restrictions]
7412  // The num_threads expression must evaluate to a positive integer value.
7413  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
7414  /*StrictlyPositive=*/true))
7415  return nullptr;
7416 
7417  return new (Context)
7418  OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
7419 }
7420 
7421 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
7422  OpenMPClauseKind CKind,
7423  bool StrictlyPositive) {
7424  if (!E)
7425  return ExprError();
7426  if (E->isValueDependent() || E->isTypeDependent() ||
7428  return E;
7429  llvm::APSInt Result;
7430  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
7431  if (ICE.isInvalid())
7432  return ExprError();
7433  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
7434  (!StrictlyPositive && !Result.isNonNegative())) {
7435  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
7436  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
7437  << E->getSourceRange();
7438  return ExprError();
7439  }
7440  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
7441  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
7442  << E->getSourceRange();
7443  return ExprError();
7444  }
7445  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
7446  DSAStack->setAssociatedLoops(Result.getExtValue());
7447  else if (CKind == OMPC_ordered)
7448  DSAStack->setAssociatedLoops(Result.getExtValue());
7449  return ICE;
7450 }
7451 
7453  SourceLocation LParenLoc,
7454  SourceLocation EndLoc) {
7455  // OpenMP [2.8.1, simd construct, Description]
7456  // The parameter of the safelen clause must be a constant
7457  // positive integer expression.
7458  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
7459  if (Safelen.isInvalid())
7460  return nullptr;
7461  return new (Context)
7462  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
7463 }
7464 
7466  SourceLocation LParenLoc,
7467  SourceLocation EndLoc) {
7468  // OpenMP [2.8.1, simd construct, Description]
7469  // The parameter of the simdlen clause must be a constant
7470  // positive integer expression.
7471  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
7472  if (Simdlen.isInvalid())
7473  return nullptr;
7474  return new (Context)
7475  OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
7476 }
7477 
7479  SourceLocation StartLoc,
7480  SourceLocation LParenLoc,
7481  SourceLocation EndLoc) {
7482  // OpenMP [2.7.1, loop construct, Description]
7483  // OpenMP [2.8.1, simd construct, Description]
7484  // OpenMP [2.9.6, distribute construct, Description]
7485  // The parameter of the collapse clause must be a constant
7486  // positive integer expression.
7487  ExprResult NumForLoopsResult =
7488  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
7489  if (NumForLoopsResult.isInvalid())
7490  return nullptr;
7491  return new (Context)
7492  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
7493 }
7494 
7496  SourceLocation EndLoc,
7497  SourceLocation LParenLoc,
7498  Expr *NumForLoops) {
7499  // OpenMP [2.7.1, loop construct, Description]
7500  // OpenMP [2.8.1, simd construct, Description]
7501  // OpenMP [2.9.6, distribute construct, Description]
7502  // The parameter of the ordered clause must be a constant
7503  // positive integer expression if any.
7504  if (NumForLoops && LParenLoc.isValid()) {
7505  ExprResult NumForLoopsResult =
7506  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
7507  if (NumForLoopsResult.isInvalid())
7508  return nullptr;
7509  NumForLoops = NumForLoopsResult.get();
7510  } else
7511  NumForLoops = nullptr;
7512  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops);
7513  return new (Context)
7514  OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc);
7515 }
7516 
7518  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
7519  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
7520  OMPClause *Res = nullptr;
7521  switch (Kind) {
7522  case OMPC_default:
7523  Res =
7524  ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
7525  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
7526  break;
7527  case OMPC_proc_bind:
7529  static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
7530  LParenLoc, EndLoc);
7531  break;
7532  case OMPC_if:
7533  case OMPC_final:
7534  case OMPC_num_threads:
7535  case OMPC_safelen:
7536  case OMPC_simdlen:
7537  case OMPC_collapse:
7538  case OMPC_schedule:
7539  case OMPC_private:
7540  case OMPC_firstprivate:
7541  case OMPC_lastprivate:
7542  case OMPC_shared:
7543  case OMPC_reduction:
7544  case OMPC_linear:
7545  case OMPC_aligned:
7546  case OMPC_copyin:
7547  case OMPC_copyprivate:
7548  case OMPC_ordered:
7549  case OMPC_nowait:
7550  case OMPC_untied:
7551  case OMPC_mergeable:
7552  case OMPC_threadprivate:
7553  case OMPC_flush:
7554  case OMPC_read:
7555  case OMPC_write:
7556  case OMPC_update:
7557  case OMPC_capture:
7558  case OMPC_seq_cst:
7559  case OMPC_depend:
7560  case OMPC_device:
7561  case OMPC_threads:
7562  case OMPC_simd:
7563  case OMPC_map:
7564  case OMPC_num_teams:
7565  case OMPC_thread_limit:
7566  case OMPC_priority:
7567  case OMPC_grainsize:
7568  case OMPC_nogroup:
7569  case OMPC_num_tasks:
7570  case OMPC_hint:
7571  case OMPC_dist_schedule:
7572  case OMPC_defaultmap:
7573  case OMPC_unknown:
7574  case OMPC_uniform:
7575  case OMPC_to:
7576  case OMPC_from:
7577  case OMPC_use_device_ptr:
7578  case OMPC_is_device_ptr:
7579  llvm_unreachable("Clause is not allowed.");
7580  }
7581  return Res;
7582 }
7583 
7584 static std::string
7585 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
7586  ArrayRef<unsigned> Exclude = llvm::None) {
7587  std::string Values;
7588  unsigned Bound = Last >= 2 ? Last - 2 : 0;
7589  unsigned Skipped = Exclude.size();
7590  auto S = Exclude.begin(), E = Exclude.end();
7591  for (unsigned i = First; i < Last; ++i) {
7592  if (std::find(S, E, i) != E) {
7593  --Skipped;
7594  continue;
7595  }
7596  Values += "'";
7597  Values += getOpenMPSimpleClauseTypeName(K, i);
7598  Values += "'";
7599  if (i == Bound - Skipped)
7600  Values += " or ";
7601  else if (i != Bound + 1 - Skipped)
7602  Values += ", ";
7603  }
7604  return Values;
7605 }
7606 
7608  SourceLocation KindKwLoc,
7609  SourceLocation StartLoc,
7610  SourceLocation LParenLoc,
7611  SourceLocation EndLoc) {
7612  if (Kind == OMPC_DEFAULT_unknown) {
7613  static_assert(OMPC_DEFAULT_unknown > 0,
7614  "OMPC_DEFAULT_unknown not greater than 0");
7615  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
7616  << getListOfPossibleValues(OMPC_default, /*First=*/0,
7617  /*Last=*/OMPC_DEFAULT_unknown)
7618  << getOpenMPClauseName(OMPC_default);
7619  return nullptr;
7620  }
7621  switch (Kind) {
7622  case OMPC_DEFAULT_none:
7623  DSAStack->setDefaultDSANone(KindKwLoc);
7624  break;
7625  case OMPC_DEFAULT_shared:
7626  DSAStack->setDefaultDSAShared(KindKwLoc);
7627  break;
7628  case OMPC_DEFAULT_unknown:
7629  llvm_unreachable("Clause kind is not allowed.");
7630  break;
7631  }
7632  return new (Context)
7633  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
7634 }
7635 
7637  SourceLocation KindKwLoc,
7638  SourceLocation StartLoc,
7639  SourceLocation LParenLoc,
7640  SourceLocation EndLoc) {
7641  if (Kind == OMPC_PROC_BIND_unknown) {
7642  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
7643  << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
7644  /*Last=*/OMPC_PROC_BIND_unknown)
7645  << getOpenMPClauseName(OMPC_proc_bind);
7646  return nullptr;
7647  }
7648  return new (Context)
7649  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
7650 }
7651 
7654  SourceLocation StartLoc, SourceLocation LParenLoc,
7655  ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
7656  SourceLocation EndLoc) {
7657  OMPClause *Res = nullptr;
7658  switch (Kind) {
7659  case OMPC_schedule:
7660  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
7661  assert(Argument.size() == NumberOfElements &&
7662  ArgumentLoc.size() == NumberOfElements);
7664  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
7665  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
7666  static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
7667  StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
7668  ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
7669  break;
7670  case OMPC_if:
7671  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
7672  Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
7673  Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
7674  DelimLoc, EndLoc);
7675  break;
7676  case OMPC_dist_schedule:
7678  static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
7679  StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
7680  break;
7681  case OMPC_defaultmap:
7682  enum { Modifier, DefaultmapKind };
7684  static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
7685  static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
7686  StartLoc, LParenLoc, ArgumentLoc[Modifier],
7687  ArgumentLoc[DefaultmapKind], EndLoc);
7688  break;
7689  case OMPC_final:
7690  case OMPC_num_threads:
7691  case OMPC_safelen:
7692  case OMPC_simdlen:
7693  case OMPC_collapse:
7694  case OMPC_default:
7695  case OMPC_proc_bind:
7696  case OMPC_private:
7697  case OMPC_firstprivate:
7698  case OMPC_lastprivate:
7699  case OMPC_shared:
7700  case OMPC_reduction:
7701  case OMPC_linear:
7702  case OMPC_aligned:
7703  case OMPC_copyin:
7704  case OMPC_copyprivate:
7705  case OMPC_ordered:
7706  case OMPC_nowait:
7707  case OMPC_untied:
7708  case OMPC_mergeable:
7709  case OMPC_threadprivate:
7710  case OMPC_flush:
7711  case OMPC_read:
7712  case OMPC_write:
7713  case OMPC_update:
7714  case OMPC_capture:
7715  case OMPC_seq_cst:
7716  case OMPC_depend:
7717  case OMPC_device:
7718  case OMPC_threads:
7719  case OMPC_simd:
7720  case OMPC_map:
7721  case OMPC_num_teams:
7722  case OMPC_thread_limit:
7723  case OMPC_priority:
7724  case OMPC_grainsize:
7725  case OMPC_nogroup:
7726  case OMPC_num_tasks:
7727  case OMPC_hint:
7728  case OMPC_unknown:
7729  case OMPC_uniform:
7730  case OMPC_to:
7731  case OMPC_from:
7732  case OMPC_use_device_ptr:
7733  case OMPC_is_device_ptr:
7734  llvm_unreachable("Clause is not allowed.");
7735  }
7736  return Res;
7737 }
7738 
7741  SourceLocation M1Loc, SourceLocation M2Loc) {
7742  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
7743  SmallVector<unsigned, 2> Excluded;
7745  Excluded.push_back(M2);
7746  if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
7747  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
7748  if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
7749  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
7750  S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
7751  << getListOfPossibleValues(OMPC_schedule,
7752  /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
7753  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
7754  Excluded)
7755  << getOpenMPClauseName(OMPC_schedule);
7756  return true;
7757  }
7758  return false;
7759 }
7760 
7763  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
7764  SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
7765  SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
7766  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
7767  checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
7768  return nullptr;
7769  // OpenMP, 2.7.1, Loop Construct, Restrictions
7770  // Either the monotonic modifier or the nonmonotonic modifier can be specified
7771  // but not both.
7772  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
7773  (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
7774  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
7775  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
7776  M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
7777  Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
7778  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
7779  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
7780  return nullptr;
7781  }
7782  if (Kind == OMPC_SCHEDULE_unknown) {
7783  std::string Values;
7784  if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
7785  unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
7786  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
7787  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
7788  Exclude);
7789  } else {
7790  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
7791  /*Last=*/OMPC_SCHEDULE_unknown);
7792  }
7793  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
7794  << Values << getOpenMPClauseName(OMPC_schedule);
7795  return nullptr;
7796  }
7797  // OpenMP, 2.7.1, Loop Construct, Restrictions
7798  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
7799  // schedule(guided).
7800  if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
7801  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
7802  Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
7803  Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
7804  diag::err_omp_schedule_nonmonotonic_static);
7805  return nullptr;
7806  }
7807  Expr *ValExpr = ChunkSize;
7808  Stmt *HelperValStmt = nullptr;
7809  if (ChunkSize) {
7810  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
7811  !ChunkSize->isInstantiationDependent() &&
7812  !ChunkSize->containsUnexpandedParameterPack()) {
7813  SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
7814  ExprResult Val =
7815  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
7816  if (Val.isInvalid())
7817  return nullptr;
7818 
7819  ValExpr = Val.get();
7820 
7821  // OpenMP [2.7.1, Restrictions]
7822  // chunk_size must be a loop invariant integer expression with a positive
7823  // value.
7824  llvm::APSInt Result;
7825  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
7826  if (Result.isSigned() && !Result.isStrictlyPositive()) {
7827  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
7828  << "schedule" << 1 << ChunkSize->getSourceRange();
7829  return nullptr;
7830  }
7831  } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) &&
7833  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
7834  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
7835  HelperValStmt = buildPreInits(Context, Captures);
7836  }
7837  }
7838  }
7839 
7840  return new (Context)
7841  OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
7842  ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
7843 }
7844 
7846  SourceLocation StartLoc,
7847  SourceLocation EndLoc) {
7848  OMPClause *Res = nullptr;
7849  switch (Kind) {
7850  case OMPC_ordered:
7851  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
7852  break;
7853  case OMPC_nowait:
7854  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
7855  break;
7856  case OMPC_untied:
7857  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
7858  break;
7859  case OMPC_mergeable:
7860  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
7861  break;
7862  case OMPC_read:
7863  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
7864  break;
7865  case OMPC_write:
7866  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
7867  break;
7868  case OMPC_update:
7869  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
7870  break;
7871  case OMPC_capture:
7872  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
7873  break;
7874  case OMPC_seq_cst:
7875  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
7876  break;
7877  case OMPC_threads:
7878  Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
7879  break;
7880  case OMPC_simd:
7881  Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
7882  break;
7883  case OMPC_nogroup:
7884  Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
7885  break;
7886  case OMPC_if:
7887  case OMPC_final:
7888  case OMPC_num_threads:
7889  case OMPC_safelen:
7890  case OMPC_simdlen:
7891  case OMPC_collapse:
7892  case OMPC_schedule:
7893  case OMPC_private:
7894  case OMPC_firstprivate:
7895  case OMPC_lastprivate:
7896  case OMPC_shared:
7897  case OMPC_reduction:
7898  case OMPC_linear:
7899  case OMPC_aligned:
7900  case OMPC_copyin:
7901  case OMPC_copyprivate:
7902  case OMPC_default:
7903  case OMPC_proc_bind:
7904  case OMPC_threadprivate:
7905  case OMPC_flush:
7906  case OMPC_depend:
7907  case OMPC_device:
7908  case OMPC_map:
7909  case OMPC_num_teams:
7910  case OMPC_thread_limit:
7911  case OMPC_priority:
7912  case OMPC_grainsize:
7913  case OMPC_num_tasks:
7914  case OMPC_hint:
7915  case OMPC_dist_schedule:
7916  case OMPC_defaultmap:
7917  case OMPC_unknown:
7918  case OMPC_uniform:
7919  case OMPC_to:
7920  case OMPC_from:
7921  case OMPC_use_device_ptr:
7922  case OMPC_is_device_ptr:
7923  llvm_unreachable("Clause is not allowed.");
7924  }
7925  return Res;
7926 }
7927 
7929  SourceLocation EndLoc) {
7930  DSAStack->setNowaitRegion();
7931  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
7932 }
7933 
7935  SourceLocation EndLoc) {
7936  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
7937 }
7938 
7940  SourceLocation EndLoc) {
7941  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
7942 }
7943 
7945  SourceLocation EndLoc) {
7946  return new (Context) OMPReadClause(StartLoc, EndLoc);
7947 }
7948 
7950  SourceLocation EndLoc) {
7951  return new (Context) OMPWriteClause(StartLoc, EndLoc);
7952 }
7953 
7955  SourceLocation EndLoc) {
7956  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
7957 }
7958 
7960  SourceLocation EndLoc) {
7961  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
7962 }
7963 
7965  SourceLocation EndLoc) {
7966  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
7967 }
7968 
7970  SourceLocation EndLoc) {
7971  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
7972 }
7973 
7975  SourceLocation EndLoc) {
7976  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
7977 }
7978 
7980  SourceLocation EndLoc) {
7981  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
7982 }
7983 
7985  OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
7987  SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
7988  const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
7989  OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
7990  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
7991  SourceLocation DepLinMapLoc) {
7992  OMPClause *Res = nullptr;
7993  switch (Kind) {
7994  case OMPC_private:
7995  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
7996  break;
7997  case OMPC_firstprivate:
7998  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
7999  break;
8000  case OMPC_lastprivate:
8001  Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8002  break;
8003  case OMPC_shared:
8004  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
8005  break;
8006  case OMPC_reduction:
8007  Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8008  EndLoc, ReductionIdScopeSpec, ReductionId);
8009  break;
8010  case OMPC_linear:
8011  Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
8012  LinKind, DepLinMapLoc, ColonLoc, EndLoc);
8013  break;
8014  case OMPC_aligned:
8015  Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
8016  ColonLoc, EndLoc);
8017  break;
8018  case OMPC_copyin:
8019  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
8020  break;
8021  case OMPC_copyprivate:
8022  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8023  break;
8024  case OMPC_flush:
8025  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
8026  break;
8027  case OMPC_depend:
8028  Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
8029  StartLoc, LParenLoc, EndLoc);
8030  break;
8031  case OMPC_map:
8032  Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
8033  DepLinMapLoc, ColonLoc, VarList, StartLoc,
8034  LParenLoc, EndLoc);
8035  break;
8036  case OMPC_to:
8037  Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
8038  break;
8039  case OMPC_from:
8040  Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
8041  break;
8042  case OMPC_use_device_ptr:
8043  Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8044  break;
8045  case OMPC_is_device_ptr:
8046  Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8047  break;
8048  case OMPC_if:
8049  case OMPC_final:
8050  case OMPC_num_threads:
8051  case OMPC_safelen:
8052  case OMPC_simdlen:
8053  case OMPC_collapse:
8054  case OMPC_default:
8055  case OMPC_proc_bind:
8056  case OMPC_schedule:
8057  case OMPC_ordered:
8058  case OMPC_nowait:
8059  case OMPC_untied:
8060  case OMPC_mergeable:
8061  case OMPC_threadprivate:
8062  case OMPC_read:
8063  case OMPC_write:
8064  case OMPC_update:
8065  case OMPC_capture:
8066  case OMPC_seq_cst:
8067  case OMPC_device:
8068  case OMPC_threads:
8069  case OMPC_simd:
8070  case OMPC_num_teams:
8071  case OMPC_thread_limit:
8072  case OMPC_priority:
8073  case OMPC_grainsize:
8074  case OMPC_nogroup:
8075  case OMPC_num_tasks:
8076  case OMPC_hint:
8077  case OMPC_dist_schedule:
8078  case OMPC_defaultmap:
8079  case OMPC_unknown:
8080  case OMPC_uniform:
8081  llvm_unreachable("Clause is not allowed.");
8082  }
8083  return Res;
8084 }
8085 
8087  ExprObjectKind OK, SourceLocation Loc) {
8089  Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
8090  if (!Res.isUsable())
8091  return ExprError();
8092  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
8093  Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
8094  if (!Res.isUsable())
8095  return ExprError();
8096  }
8097  if (VK != VK_LValue && Res.get()->isGLValue()) {
8098  Res = DefaultLvalueConversion(Res.get());
8099  if (!Res.isUsable())
8100  return ExprError();
8101  }
8102  return Res;
8103 }
8104 
8105 static std::pair<ValueDecl *, bool>
8107  SourceRange &ERange, bool AllowArraySection = false) {
8108  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
8110  return std::make_pair(nullptr, true);
8111 
8112  // OpenMP [3.1, C/C++]
8113  // A list item is a variable name.
8114  // OpenMP [2.9.3.3, Restrictions, p.1]
8115  // A variable that is part of another variable (as an array or
8116  // structure element) cannot appear in a private clause.
8117  RefExpr = RefExpr->IgnoreParens();
8118  enum {
8119  NoArrayExpr = -1,
8120  ArraySubscript = 0,
8121  OMPArraySection = 1
8122  } IsArrayExpr = NoArrayExpr;
8123  if (AllowArraySection) {
8124  if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
8125  auto *Base = ASE->getBase()->IgnoreParenImpCasts();
8126  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
8127  Base = TempASE->getBase()->IgnoreParenImpCasts();
8128  RefExpr = Base;
8129  IsArrayExpr = ArraySubscript;
8130  } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
8131  auto *Base = OASE->getBase()->IgnoreParenImpCasts();
8132  while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
8133  Base = TempOASE->getBase()->IgnoreParenImpCasts();
8134  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
8135  Base = TempASE->getBase()->IgnoreParenImpCasts();
8136  RefExpr = Base;
8137  IsArrayExpr = OMPArraySection;
8138  }
8139  }
8140  ELoc = RefExpr->getExprLoc();
8141  ERange = RefExpr->getSourceRange();
8142  RefExpr = RefExpr->IgnoreParenImpCasts();
8143  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
8144  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
8145  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
8146  (S.getCurrentThisType().isNull() || !ME ||
8147  !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
8148  !isa<FieldDecl>(ME->getMemberDecl()))) {
8149  if (IsArrayExpr != NoArrayExpr)
8150  S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
8151  << ERange;
8152  else {
8153  S.Diag(ELoc,
8154  AllowArraySection
8155  ? diag::err_omp_expected_var_name_member_expr_or_array_item
8156  : diag::err_omp_expected_var_name_member_expr)
8157  << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
8158  }
8159  return std::make_pair(nullptr, false);
8160  }
8161  return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(), false);
8162 }
8163 
8165  SourceLocation StartLoc,
8166  SourceLocation LParenLoc,
8167  SourceLocation EndLoc) {
8169  SmallVector<Expr *, 8> PrivateCopies;
8170  for (auto &RefExpr : VarList) {
8171  assert(RefExpr && "NULL expr in OpenMP private clause.");
8172  SourceLocation ELoc;
8173  SourceRange ERange;
8174  Expr *SimpleRefExpr = RefExpr;
8175  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
8176  if (Res.second) {
8177  // It will be analyzed later.
8178  Vars.push_back(RefExpr);
8179  PrivateCopies.push_back(nullptr);
8180  }
8181  ValueDecl *D = Res.first;
8182  if (!D)
8183  continue;
8184 
8185  QualType Type = D->getType();
8186  auto *VD = dyn_cast<VarDecl>(D);
8187 
8188  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
8189  // A variable that appears in a private clause must not have an incomplete
8190  // type or a reference type.
8191  if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
8192  continue;
8193  Type = Type.getNonReferenceType();
8194 
8195  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
8196  // in a Construct]
8197  // Variables with the predetermined data-sharing attributes may not be
8198  // listed in data-sharing attributes clauses, except for the cases
8199  // listed below. For these exceptions only, listing a predetermined
8200  // variable in a data-sharing attribute clause is allowed and overrides
8201  // the variable's predetermined data-sharing attributes.
8202  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
8203  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
8204  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
8205  << getOpenMPClauseName(OMPC_private);
8206  ReportOriginalDSA(*this, DSAStack, D, DVar);
8207  continue;
8208  }
8209 
8210  // Variably modified types are not supported for tasks.
8211  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
8212  isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
8213  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
8214  << getOpenMPClauseName(OMPC_private) << Type
8215  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
8216  bool IsDecl =
8217  !VD ||
8218  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
8219  Diag(D->getLocation(),
8220  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
8221  << D;
8222  continue;
8223  }
8224 
8225  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
8226  // A list item cannot appear in both a map clause and a data-sharing
8227  // attribute clause on the same construct
8228  if (DSAStack->getCurrentDirective() == OMPD_target) {
8229  if (DSAStack->checkMappableExprComponentListsForDecl(
8230  VD, /* CurrentRegionOnly = */ true,
8232  -> bool { return true; })) {
8233  Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
8234  << getOpenMPClauseName(OMPC_private)
8235  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
8236  ReportOriginalDSA(*this, DSAStack, D, DVar);
8237  continue;
8238  }
8239  }
8240 
8241  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
8242  // A variable of class type (or array thereof) that appears in a private
8243  // clause requires an accessible, unambiguous default constructor for the
8244  // class type.
8245  // Generate helper private variable and initialize it with the default
8246  // value. The address of the original variable is replaced by the address of
8247  // the new private variable in CodeGen. This new variable is not added to
8248  // IdResolver, so the code in the OpenMP region uses original variable for
8249  // proper diagnostics.
8250  Type = Type.getUnqualifiedType();
8251  auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
8252  D->hasAttrs() ? &D->getAttrs() : nullptr);
8253  ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
8254  if (VDPrivate->isInvalidDecl())
8255  continue;
8256  auto VDPrivateRefExpr = buildDeclRefExpr(
8257  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
8258 
8259  DeclRefExpr *Ref = nullptr;
8260  if (!VD && !CurContext->isDependentContext())
8261  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
8262  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
8263  Vars.push_back((VD || CurContext->isDependentContext())
8264  ? RefExpr->IgnoreParens()
8265  : Ref);
8266  PrivateCopies.push_back(VDPrivateRefExpr);
8267  }
8268 
8269  if (Vars.empty())
8270  return nullptr;
8271 
8272  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
8273  PrivateCopies);
8274 }
8275 
8276 namespace {
8277 class DiagsUninitializedSeveretyRAII {
8278 private:
8280  SourceLocation SavedLoc;
8281  bool IsIgnored;
8282 
8283 public:
8284  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
8285  bool IsIgnored)
8286  : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
8287  if (!IsIgnored) {
8288  Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
8289  /*Map*/ diag::Severity::Ignored, Loc);
8290  }
8291  }
8292  ~DiagsUninitializedSeveretyRAII() {
8293  if (!IsIgnored)
8294  Diags.popMappings(SavedLoc);
8295  }
8296 };
8297 }
8298 
8300  SourceLocation StartLoc,
8301  SourceLocation LParenLoc,
8302  SourceLocation EndLoc) {
8304  SmallVector<Expr *, 8> PrivateCopies;
8306  SmallVector<Decl *, 4> ExprCaptures;
8307  bool IsImplicitClause =
8308  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
8309  auto ImplicitClauseLoc = DSAStack->getConstructLoc();
8310 
8311  for (auto &RefExpr : VarList) {
8312  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
8313  SourceLocation ELoc;
8314  SourceRange ERange;
8315  Expr *SimpleRefExpr = RefExpr;
8316  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
8317  if (Res.second) {
8318  // It will be analyzed later.
8319  Vars.push_back(RefExpr);
8320  PrivateCopies.push_back(nullptr);
8321  Inits.push_back(nullptr);
8322  }
8323  ValueDecl *D = Res.first;
8324  if (!D)
8325  continue;
8326 
8327  ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
8328  QualType Type = D->getType();
8329  auto *VD = dyn_cast<VarDecl>(D);
8330 
8331  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
8332  // A variable that appears in a private clause must not have an incomplete
8333  // type or a reference type.
8334  if (RequireCompleteType(ELoc, Type,
8335  diag::err_omp_firstprivate_incomplete_type))
8336  continue;
8337  Type = Type.getNonReferenceType();
8338 
8339  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
8340  // A variable of class type (or array thereof) that appears in a private
8341  // clause requires an accessible, unambiguous copy constructor for the
8342  // class type.
8343  auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
8344 
8345  // If an implicit firstprivate variable found it was checked already.
8346  DSAStackTy::DSAVarData TopDVar;
8347  if (!IsImplicitClause) {
8348  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
8349  TopDVar = DVar;
8350  bool IsConstant = ElemType.isConstant(Context);
8351  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
8352  // A list item that specifies a given variable may not appear in more
8353  // than one clause on the same directive, except that a variable may be
8354  // specified in both firstprivate and lastprivate clauses.
8355  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
8356  DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
8357  Diag(ELoc, diag::err_omp_wrong_dsa)
8358  << getOpenMPClauseName(DVar.CKind)
8359  << getOpenMPClauseName(OMPC_firstprivate);
8360  ReportOriginalDSA(*this, DSAStack, D, DVar);
8361  continue;
8362  }
8363 
8364  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
8365  // in a Construct]
8366  // Variables with the predetermined data-sharing attributes may not be
8367  // listed in data-sharing attributes clauses, except for the cases
8368  // listed below. For these exceptions only, listing a predetermined
8369  // variable in a data-sharing attribute clause is allowed and overrides
8370  // the variable's predetermined data-sharing attributes.
8371  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
8372  // in a Construct, C/C++, p.2]
8373  // Variables with const-qualified type having no mutable member may be
8374  // listed in a firstprivate clause, even if they are static data members.
8375  if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
8376  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
8377  Diag(ELoc, diag::err_omp_wrong_dsa)
8378  << getOpenMPClauseName(DVar.CKind)
8379  << getOpenMPClauseName(OMPC_firstprivate);
8380  ReportOriginalDSA(*this, DSAStack, D, DVar);
8381  continue;
8382  }
8383 
8384  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
8385  // OpenMP [2.9.3.4, Restrictions, p.2]
8386  // A list item that is private within a parallel region must not appear
8387  // in a firstprivate clause on a worksharing construct if any of the
8388  // worksharing regions arising from the worksharing construct ever bind
8389  // to any of the parallel regions arising from the parallel construct.
8390  if (isOpenMPWorksharingDirective(CurrDir) &&
8391  !isOpenMPParallelDirective(CurrDir)) {
8392  DVar = DSAStack->getImplicitDSA(D, true);
8393  if (DVar.CKind != OMPC_shared &&
8394  (isOpenMPParallelDirective(DVar.DKind) ||
8395  DVar.DKind == OMPD_unknown)) {
8396  Diag(ELoc, diag::err_omp_required_access)
8397  << getOpenMPClauseName(OMPC_firstprivate)
8398  << getOpenMPClauseName(OMPC_shared);
8399  ReportOriginalDSA(*this, DSAStack, D, DVar);
8400  continue;
8401  }
8402  }
8403  // OpenMP [2.9.3.4, Restrictions, p.3]
8404  // A list item that appears in a reduction clause of a parallel construct
8405  // must not appear in a firstprivate clause on a worksharing or task
8406  // construct if any of the worksharing or task regions arising from the
8407  // worksharing or task construct ever bind to any of the parallel regions
8408  // arising from the parallel construct.
8409  // OpenMP [2.9.3.4, Restrictions, p.4]
8410  // A list item that appears in a reduction clause in worksharing
8411  // construct must not appear in a firstprivate clause in a task construct
8412  // encountered during execution of any of the worksharing regions arising
8413  // from the worksharing construct.
8414  if (isOpenMPTaskingDirective(CurrDir)) {
8415  DVar = DSAStack->hasInnermostDSA(
8416  D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
8417  [](OpenMPDirectiveKind K) -> bool {
8418  return isOpenMPParallelDirective(K) ||
8420  },
8421  false);
8422  if (DVar.CKind == OMPC_reduction &&
8423  (isOpenMPParallelDirective(DVar.DKind) ||
8424  isOpenMPWorksharingDirective(DVar.DKind))) {
8425  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
8426  << getOpenMPDirectiveName(DVar.DKind);
8427  ReportOriginalDSA(*this, DSAStack, D, DVar);
8428  continue;
8429  }
8430  }
8431 
8432  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
8433  // A list item that is private within a teams region must not appear in a
8434  // firstprivate clause on a distribute construct if any of the distribute
8435  // regions arising from the distribute construct ever bind to any of the
8436  // teams regions arising from the teams construct.
8437  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
8438  // A list item that appears in a reduction clause of a teams construct
8439  // must not appear in a firstprivate clause on a distribute construct if
8440  // any of the distribute regions arising from the distribute construct
8441  // ever bind to any of the teams regions arising from the teams construct.
8442  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
8443  // A list item may appear in a firstprivate or lastprivate clause but not
8444  // both.
8445  if (CurrDir == OMPD_distribute) {
8446  DVar = DSAStack->hasInnermostDSA(
8447  D, [](OpenMPClauseKind C) -> bool { return C == OMPC_private; },
8448  [](OpenMPDirectiveKind K) -> bool {
8449  return isOpenMPTeamsDirective(K);
8450  },
8451  false);
8452  if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) {
8453  Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams);
8454  ReportOriginalDSA(*this, DSAStack, D, DVar);
8455  continue;
8456  }
8457  DVar = DSAStack->hasInnermostDSA(
8458  D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
8459  [](OpenMPDirectiveKind K) -> bool {
8460  return isOpenMPTeamsDirective(K);
8461  },
8462  false);
8463  if (DVar.CKind == OMPC_reduction &&
8464  isOpenMPTeamsDirective(DVar.DKind)) {
8465  Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction);
8466  ReportOriginalDSA(*this, DSAStack, D, DVar);
8467  continue;
8468  }
8469  DVar = DSAStack->getTopDSA(D, false);
8470  if (DVar.CKind == OMPC_lastprivate) {
8471  Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
8472  ReportOriginalDSA(*this, DSAStack, D, DVar);
8473  continue;
8474  }
8475  }
8476  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
8477  // A list item cannot appear in both a map clause and a data-sharing
8478  // attribute clause on the same construct
8479  if (CurrDir == OMPD_target) {
8480  if (DSAStack->checkMappableExprComponentListsForDecl(
8481  VD, /* CurrentRegionOnly = */ true,
8483  -> bool { return true; })) {
8484  Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
8485  << getOpenMPClauseName(OMPC_firstprivate)
8486  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
8487  ReportOriginalDSA(*this, DSAStack, D, DVar);
8488  continue;
8489  }
8490  }
8491  }
8492 
8493  // Variably modified types are not supported for tasks.
8494  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
8495  isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
8496  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
8497  << getOpenMPClauseName(OMPC_firstprivate) << Type
8498  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
8499  bool IsDecl =
8500  !VD ||
8501  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
8502  Diag(D->getLocation(),
8503  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
8504  << D;
8505  continue;
8506  }
8507 
8508  Type = Type.getUnqualifiedType();
8509  auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
8510  D->hasAttrs() ? &D->getAttrs() : nullptr);
8511  // Generate helper private variable and initialize it with the value of the
8512  // original variable. The address of the original variable is replaced by
8513  // the address of the new private variable in the CodeGen. This new variable
8514  // is not added to IdResolver, so the code in the OpenMP region uses
8515  // original variable for proper diagnostics and variable capturing.
8516  Expr *VDInitRefExpr = nullptr;
8517  // For arrays generate initializer for single element and replace it by the
8518  // original array element in CodeGen.
8519  if (Type->isArrayType()) {
8520  auto VDInit =
8521  buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
8522  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
8523  auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
8524  ElemType = ElemType.getUnqualifiedType();
8525  auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
8526  ".firstprivate.temp");
8527  InitializedEntity Entity =
8530 
8531  InitializationSequence InitSeq(*this, Entity, Kind, Init);
8532  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
8533  if (Result.isInvalid())
8534  VDPrivate->setInvalidDecl();
8535  else
8536  VDPrivate->setInit(Result.getAs<Expr>());
8537  // Remove temp variable declaration.
8538  Context.Deallocate(VDInitTemp);
8539  } else {
8540  auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
8541  ".firstprivate.temp");
8542  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
8543  RefExpr->getExprLoc());
8544  AddInitializerToDecl(VDPrivate,
8545  DefaultLvalueConversion(VDInitRefExpr).get(),
8546  /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
8547  }
8548  if (VDPrivate->isInvalidDecl()) {
8549  if (IsImplicitClause) {
8550  Diag(RefExpr->getExprLoc(),
8551  diag::note_omp_task_predetermined_firstprivate_here);
8552  }
8553  continue;
8554  }
8555  CurContext->addDecl(VDPrivate);
8556  auto VDPrivateRefExpr = buildDeclRefExpr(
8557  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
8558  RefExpr->getExprLoc());
8559  DeclRefExpr *Ref = nullptr;
8560  if (!VD && !CurContext->isDependentContext()) {
8561  if (TopDVar.CKind == OMPC_lastprivate)
8562  Ref = TopDVar.PrivateCopy;
8563  else {
8564  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
8565  if (!IsOpenMPCapturedDecl(D))
8566  ExprCaptures.push_back(Ref->getDecl());
8567  }
8568  }
8569  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
8570  Vars.push_back((VD || CurContext->isDependentContext())
8571  ? RefExpr->IgnoreParens()
8572  : Ref);
8573  PrivateCopies.push_back(VDPrivateRefExpr);
8574  Inits.push_back(VDInitRefExpr);
8575  }
8576 
8577  if (Vars.empty())
8578  return nullptr;
8579 
8580  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
8581  Vars, PrivateCopies, Inits,
8582  buildPreInits(Context, ExprCaptures));
8583 }
8584 
8586  SourceLocation StartLoc,
8587  SourceLocation LParenLoc,
8588  SourceLocation EndLoc) {
8590  SmallVector<Expr *, 8> SrcExprs;
8591  SmallVector<Expr *, 8> DstExprs;
8592  SmallVector<Expr *, 8> AssignmentOps;
8593  SmallVector<Decl *, 4> ExprCaptures;
8594  SmallVector<Expr *, 4> ExprPostUpdates;
8595  for (auto &RefExpr : VarList) {
8596  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
8597  SourceLocation ELoc;
8598  SourceRange ERange;
8599  Expr *SimpleRefExpr = RefExpr;
8600  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
8601  if (Res.second) {
8602  // It will be analyzed later.
8603  Vars.push_back(RefExpr);
8604  SrcExprs.push_back(nullptr);
8605  DstExprs.push_back(nullptr);
8606  AssignmentOps.push_back(nullptr);
8607  }
8608  ValueDecl *D = Res.first;
8609  if (!D)
8610  continue;
8611 
8612  QualType Type = D->getType();
8613  auto *VD = dyn_cast<VarDecl>(D);
8614 
8615  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
8616  // A variable that appears in a lastprivate clause must not have an
8617  // incomplete type or a reference type.
8618  if (RequireCompleteType(ELoc, Type,
8619  diag::err_omp_lastprivate_incomplete_type))
8620  continue;
8621  Type = Type.getNonReferenceType();
8622 
8623  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
8624  // in a Construct]
8625  // Variables with the predetermined data-sharing attributes may not be
8626  // listed in data-sharing attributes clauses, except for the cases
8627  // listed below.
8628  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
8629  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
8630  DVar.CKind != OMPC_firstprivate &&
8631  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
8632  Diag(ELoc, diag::err_omp_wrong_dsa)
8633  << getOpenMPClauseName(DVar.CKind)
8634  << getOpenMPClauseName(OMPC_lastprivate);
8635  ReportOriginalDSA(*this, DSAStack, D, DVar);
8636  continue;
8637  }
8638 
8639  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
8640  // OpenMP [2.14.3.5, Restrictions, p.2]
8641  // A list item that is private within a parallel region, or that appears in
8642  // the reduction clause of a parallel construct, must not appear in a
8643  // lastprivate clause on a worksharing construct if any of the corresponding
8644  // worksharing regions ever binds to any of the corresponding parallel
8645  // regions.
8646  DSAStackTy::DSAVarData TopDVar = DVar;
8647  if (isOpenMPWorksharingDirective(CurrDir) &&
8648  !isOpenMPParallelDirective(CurrDir)) {
8649  DVar = DSAStack->getImplicitDSA(D, true);
8650  if (DVar.CKind != OMPC_shared) {
8651  Diag(ELoc, diag::err_omp_required_access)
8652  << getOpenMPClauseName(OMPC_lastprivate)
8653  << getOpenMPClauseName(OMPC_shared);
8654  ReportOriginalDSA(*this, DSAStack, D, DVar);
8655  continue;
8656  }
8657  }
8658 
8659  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
8660  // A list item may appear in a firstprivate or lastprivate clause but not
8661  // both.
8662  if (CurrDir == OMPD_distribute) {
8663  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
8664  if (DVar.CKind == OMPC_firstprivate) {
8665  Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
8666  ReportOriginalDSA(*this, DSAStack, D, DVar);
8667  continue;
8668  }
8669  }
8670 
8671  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
8672  // A variable of class type (or array thereof) that appears in a
8673  // lastprivate clause requires an accessible, unambiguous default
8674  // constructor for the class type, unless the list item is also specified
8675  // in a firstprivate clause.
8676  // A variable of class type (or array thereof) that appears in a
8677  // lastprivate clause requires an accessible, unambiguous copy assignment
8678  // operator for the class type.
8680  auto *SrcVD = buildVarDecl(*this, ERange.getBegin(),
8681  Type.getUnqualifiedType(), ".lastprivate.src",
8682  D->hasAttrs() ? &D->getAttrs() : nullptr);
8683  auto *PseudoSrcExpr =
8684  buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
8685  auto *DstVD =
8686  buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
8687  D->hasAttrs() ? &D->getAttrs() : nullptr);
8688  auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
8689  // For arrays generate assignment operation for single element and replace
8690  // it by the original array element in CodeGen.
8691  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
8692  PseudoDstExpr, PseudoSrcExpr);
8693  if (AssignmentOp.isInvalid())
8694  continue;
8695  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
8696  /*DiscardedValue=*/true);
8697  if (AssignmentOp.isInvalid())
8698  continue;
8699 
8700  DeclRefExpr *Ref = nullptr;
8701  if (!VD && !CurContext->isDependentContext()) {
8702  if (TopDVar.CKind == OMPC_firstprivate)
8703  Ref = TopDVar.PrivateCopy;
8704  else {
8705  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
8706  if (!IsOpenMPCapturedDecl(D))
8707  ExprCaptures.push_back(Ref->getDecl());
8708  }
8709  if (TopDVar.CKind == OMPC_firstprivate ||
8710  (!IsOpenMPCapturedDecl(D) &&
8711  Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
8712  ExprResult RefRes = DefaultLvalueConversion(Ref);
8713  if (!RefRes.isUsable())
8714  continue;
8715  ExprResult PostUpdateRes =
8716  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
8717  RefRes.get());
8718  if (!PostUpdateRes.isUsable())
8719  continue;
8720  ExprPostUpdates.push_back(
8721  IgnoredValueConversions(PostUpdateRes.get()).get());
8722  }
8723  }
8724  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
8725  Vars.push_back((VD || CurContext->isDependentContext())
8726  ? RefExpr->IgnoreParens()
8727  : Ref);
8728  SrcExprs.push_back(PseudoSrcExpr);
8729  DstExprs.push_back(PseudoDstExpr);
8730  AssignmentOps.push_back(AssignmentOp.get());
8731  }
8732 
8733  if (Vars.empty())
8734  return nullptr;
8735 
8736  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
8737  Vars, SrcExprs, DstExprs, AssignmentOps,
8738  buildPreInits(Context, ExprCaptures),
8739  buildPostUpdate(*this, ExprPostUpdates));
8740 }
8741 
8743  SourceLocation StartLoc,
8744  SourceLocation LParenLoc,
8745  SourceLocation EndLoc) {
8747  for (auto &RefExpr : VarList) {
8748  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
8749  SourceLocation ELoc;
8750  SourceRange ERange;
8751  Expr *SimpleRefExpr = RefExpr;
8752  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
8753  if (Res.second) {
8754  // It will be analyzed later.
8755  Vars.push_back(RefExpr);
8756  }
8757  ValueDecl *D = Res.first;
8758  if (!D)
8759  continue;
8760 
8761  auto *VD = dyn_cast<VarDecl>(D);
8762  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
8763  // in a Construct]
8764  // Variables with the predetermined data-sharing attributes may not be
8765  // listed in data-sharing attributes clauses, except for the cases
8766  // listed below. For these exceptions only, listing a predetermined
8767  // variable in a data-sharing attribute clause is allowed and overrides
8768  // the variable's predetermined data-sharing attributes.
8769  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
8770  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
8771  DVar.RefExpr) {
8772  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
8773  << getOpenMPClauseName(OMPC_shared);
8774  ReportOriginalDSA(*this, DSAStack, D, DVar);
8775  continue;
8776  }
8777 
8778  DeclRefExpr *Ref = nullptr;
8779  if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
8780  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
8781  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
8782  Vars.push_back((VD || !Ref || CurContext->isDependentContext())
8783  ? RefExpr->IgnoreParens()
8784  : Ref);
8785  }
8786 
8787  if (Vars.empty())
8788  return nullptr;
8789 
8790  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
8791 }
8792 
8793 namespace {
8794 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
8795  DSAStackTy *Stack;
8796 
8797 public:
8798  bool VisitDeclRefExpr(DeclRefExpr *E) {
8799  if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
8800  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false);
8801  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
8802  return false;
8803  if (DVar.CKind != OMPC_unknown)
8804  return true;
8805  DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
8806  VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
8807  false);
8808  if (DVarPrivate.CKind != OMPC_unknown)
8809  return true;
8810  return false;
8811  }
8812  return false;
8813  }
8814  bool VisitStmt(Stmt *S) {
8815  for (auto Child : S->children()) {
8816  if (Child && Visit(Child))
8817  return true;
8818  }
8819  return false;
8820  }
8821  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
8822 };
8823 } // namespace
8824 
8825 namespace {
8826 // Transform MemberExpression for specified FieldDecl of current class to
8827 // DeclRefExpr to specified OMPCapturedExprDecl.
8828 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
8829  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
8830  ValueDecl *Field;
8831  DeclRefExpr *CapturedExpr;
8832 
8833 public:
8834  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
8835  : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
8836 
8837  ExprResult TransformMemberExpr(MemberExpr *E) {
8838  if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
8839  E->getMemberDecl() == Field) {
8840  CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
8841  return CapturedExpr;
8842  }
8843  return BaseTransform::TransformMemberExpr(E);
8844  }
8845  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
8846 };
8847 } // namespace
8848 
8849 template <typename T>
8850 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups,
8851  const llvm::function_ref<T(ValueDecl *)> &Gen) {
8852  for (auto &Set : Lookups) {
8853  for (auto *D : Set) {
8854  if (auto Res = Gen(cast<ValueDecl>(D)))
8855  return Res;
8856  }
8857  }
8858  return T();
8859 }
8860 
8861 static ExprResult
8863  Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
8864  const DeclarationNameInfo &ReductionId, QualType Ty,
8865  CXXCastPath &BasePath, Expr *UnresolvedReduction) {
8866  if (ReductionIdScopeSpec.isInvalid())
8867  return ExprError();
8868  SmallVector<UnresolvedSet<8>, 4> Lookups;
8869  if (S) {
8870  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
8871  Lookup.suppressDiagnostics();
8872  while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
8873  auto *D = Lookup.getRepresentativeDecl();
8874  do {
8875  S = S->getParent();
8876  } while (S && !S->isDeclScope(D));
8877  if (S)
8878  S = S->getParent();
8879  Lookups.push_back(UnresolvedSet<8>());
8880  Lookups.back().append(Lookup.begin(), Lookup.end());
8881  Lookup.clear();
8882  }
8883  } else if (auto *ULE =
8884  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
8885  Lookups.push_back(UnresolvedSet<8>());
8886  Decl *PrevD = nullptr;
8887  for(auto *D : ULE->decls()) {
8888  if (D == PrevD)
8889  Lookups.push_back(UnresolvedSet<8>());
8890  else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
8891  Lookups.back().addDecl(DRD);
8892  PrevD = D;
8893  }
8894  }
8895  if (Ty->isDependentType() || Ty->isInstantiationDependentType() ||
8897  filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool {
8898  return !D->isInvalidDecl() &&
8899  (D->getType()->isDependentType() ||
8902  })) {
8903  UnresolvedSet<8> ResSet;
8904  for (auto &Set : Lookups) {
8905  ResSet.append(Set.begin(), Set.end());
8906  // The last item marks the end of all declarations at the specified scope.
8907  ResSet.addDecl(Set[Set.size() - 1]);
8908  }
8910  SemaRef.Context, /*NamingClass=*/nullptr,
8911  ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
8912  /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
8913  }
8914  if (auto *VD = filterLookupForUDR<ValueDecl *>(
8915  Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
8916  if (!D->isInvalidDecl() &&
8917  SemaRef.Context.hasSameType(D->getType(), Ty))
8918  return D;
8919  return nullptr;
8920  }))
8921  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
8922  if (auto *VD = filterLookupForUDR<ValueDecl *>(
8923  Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
8924  if (!D->isInvalidDecl() &&
8925  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
8926  !Ty.isMoreQualifiedThan(D->getType()))
8927  return D;
8928  return nullptr;
8929  })) {
8930  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
8931  /*DetectVirtual=*/false);
8932  if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
8933  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
8934  VD->getType().getUnqualifiedType()))) {
8935  if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
8936  /*DiagID=*/0) !=
8938  SemaRef.BuildBasePathArray(Paths, BasePath);
8939  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
8940  }
8941  }
8942  }
8943  }
8944  if (ReductionIdScopeSpec.isSet()) {
8945  SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
8946  return ExprError();
8947  }
8948  return ExprEmpty();
8949 }
8950 
8952  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
8954  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
8955  ArrayRef<Expr *> UnresolvedReductions) {
8956  auto DN = ReductionId.getName();
8957  auto OOK = DN.getCXXOverloadedOperator();
8958  BinaryOperatorKind BOK = BO_Comma;
8959 
8960  // OpenMP [2.14.3.6, reduction clause]
8961  // C
8962  // reduction-identifier is either an identifier or one of the following
8963  // operators: +, -, *, &, |, ^, && and ||
8964  // C++
8965  // reduction-identifier is either an id-expression or one of the following
8966  // operators: +, -, *, &, |, ^, && and ||
8967  // FIXME: Only 'min' and 'max' identifiers are supported for now.
8968  switch (OOK) {
8969  case OO_Plus:
8970  case OO_Minus:
8971  BOK = BO_Add;
8972  break;
8973  case OO_Star:
8974  BOK = BO_Mul;
8975  break;
8976  case OO_Amp:
8977  BOK = BO_And;
8978  break;
8979  case OO_Pipe:
8980  BOK = BO_Or;
8981  break;
8982  case OO_Caret:
8983  BOK = BO_Xor;
8984  break;
8985  case OO_AmpAmp:
8986  BOK = BO_LAnd;
8987  break;
8988  case OO_PipePipe:
8989  BOK = BO_LOr;
8990  break;
8991  case OO_New:
8992  case OO_Delete:
8993  case OO_Array_New:
8994  case OO_Array_Delete:
8995  case OO_Slash:
8996  case OO_Percent:
8997  case OO_Tilde:
8998  case OO_Exclaim:
8999  case OO_Equal:
9000  case OO_Less:
9001  case OO_Greater:
9002  case OO_LessEqual:
9003  case OO_GreaterEqual:
9004  case OO_PlusEqual:
9005  case OO_MinusEqual:
9006  case OO_StarEqual:
9007  case OO_SlashEqual:
9008  case OO_PercentEqual:
9009  case OO_CaretEqual:
9010  case OO_AmpEqual:
9011  case OO_PipeEqual:
9012  case OO_LessLess:
9013  case OO_GreaterGreater:
9014  case OO_LessLessEqual:
9015  case OO_GreaterGreaterEqual:
9016  case OO_EqualEqual:
9017  case OO_ExclaimEqual:
9018  case OO_PlusPlus:
9019  case OO_MinusMinus:
9020  case OO_Comma:
9021  case OO_ArrowStar:
9022  case OO_Arrow:
9023  case OO_Call:
9024  case OO_Subscript:
9025  case OO_Conditional:
9026  case OO_Coawait:
9028  llvm_unreachable("Unexpected reduction identifier");
9029  case OO_None:
9030  if (auto II = DN.getAsIdentifierInfo()) {
9031  if (II->isStr("max"))
9032  BOK = BO_GT;
9033  else if (II->isStr("min"))
9034  BOK = BO_LT;
9035  }
9036  break;
9037  }
9038  SourceRange ReductionIdRange;
9039  if (ReductionIdScopeSpec.isValid())
9040  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
9041  ReductionIdRange.setEnd(ReductionId.getEndLoc());
9042 
9047  SmallVector<Expr *, 8> ReductionOps;
9048  SmallVector<Decl *, 4> ExprCaptures;
9049  SmallVector<Expr *, 4> ExprPostUpdates;
9050  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
9051  bool FirstIter = true;
9052  for (auto RefExpr : VarList) {
9053  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
9054  // OpenMP [2.1, C/C++]
9055  // A list item is a variable or array section, subject to the restrictions
9056  // specified in Section 2.4 on page 42 and in each of the sections
9057  // describing clauses and directives for which a list appears.
9058  // OpenMP [2.14.3.3, Restrictions, p.1]
9059  // A variable that is part of another variable (as an array or
9060  // structure element) cannot appear in a private clause.
9061  if (!FirstIter && IR != ER)
9062  ++IR;
9063  FirstIter = false;
9064  SourceLocation ELoc;
9065  SourceRange ERange;
9066  Expr *SimpleRefExpr = RefExpr;
9067  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
9068  /*AllowArraySection=*/true);
9069  if (Res.second) {
9070  // It will be analyzed later.
9071  Vars.push_back(RefExpr);
9072  Privates.push_back(nullptr);
9073  LHSs.push_back(nullptr);
9074  RHSs.push_back(nullptr);
9075  // Try to find 'declare reduction' corresponding construct before using
9076  // builtin/overloaded operators.
9077  QualType Type = Context.DependentTy;
9078  CXXCastPath BasePath;
9079  ExprResult DeclareReductionRef = buildDeclareReductionRef(
9080  *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec,
9081  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
9082  if (CurContext->isDependentContext() &&
9083  (DeclareReductionRef.isUnset() ||
9084  isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
9085  ReductionOps.push_back(DeclareReductionRef.get());
9086  else
9087  ReductionOps.push_back(nullptr);
9088  }
9089  ValueDecl *D = Res.first;
9090  if (!D)
9091  continue;
9092 
9093  QualType Type;
9094  auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
9095  auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
9096  if (ASE)
9097  Type = ASE->getType().getNonReferenceType();
9098  else if (OASE) {
9099  auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
9100  if (auto *ATy = BaseType->getAsArrayTypeUnsafe())
9101  Type = ATy->getElementType();
9102  else
9103  Type = BaseType->getPointeeType();
9104  Type = Type.getNonReferenceType();
9105  } else
9107  auto *VD = dyn_cast<VarDecl>(D);
9108 
9109  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9110  // A variable that appears in a private clause must not have an incomplete
9111  // type or a reference type.
9112  if (RequireCompleteType(ELoc, Type,
9113  diag::err_omp_reduction_incomplete_type))
9114  continue;
9115  // OpenMP [2.14.3.6, reduction clause, Restrictions]
9116  // A list item that appears in a reduction clause must not be
9117  // const-qualified.
9118  if (Type.getNonReferenceType().isConstant(Context)) {
9119  Diag(ELoc, diag::err_omp_const_reduction_list_item)
9120  << getOpenMPClauseName(OMPC_reduction) << Type << ERange;
9121  if (!ASE && !OASE) {
9122  bool IsDecl = !VD ||
9123  VD->isThisDeclarationADefinition(Context) ==
9125  Diag(D->getLocation(),
9126  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9127  << D;
9128  }
9129  continue;
9130  }
9131  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
9132  // If a list-item is a reference type then it must bind to the same object
9133  // for all threads of the team.
9134  if (!ASE && !OASE && VD) {
9135  VarDecl *VDDef = VD->getDefinition();
9136  if (VD->getType()->isReferenceType() && VDDef) {
9137  DSARefChecker Check(DSAStack);
9138  if (Check.Visit(VDDef->getInit())) {
9139  Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
9140  Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
9141  continue;
9142  }
9143  }
9144  }
9145 
9146  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
9147  // in a Construct]
9148  // Variables with the predetermined data-sharing attributes may not be
9149  // listed in data-sharing attributes clauses, except for the cases
9150  // listed below. For these exceptions only, listing a predetermined
9151  // variable in a data-sharing attribute clause is allowed and overrides
9152  // the variable's predetermined data-sharing attributes.
9153  // OpenMP [2.14.3.6, Restrictions, p.3]
9154  // Any number of reduction clauses can be specified on the directive,
9155  // but a list item can appear only once in the reduction clauses for that
9156  // directive.
9157  DSAStackTy::DSAVarData DVar;
9158  DVar = DSAStack->getTopDSA(D, false);
9159  if (DVar.CKind == OMPC_reduction) {
9160  Diag(ELoc, diag::err_omp_once_referenced)
9161  << getOpenMPClauseName(OMPC_reduction);
9162  if (DVar.RefExpr)
9163  Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
9164  } else if (DVar.CKind != OMPC_unknown) {
9165  Diag(ELoc, diag::err_omp_wrong_dsa)
9166  << getOpenMPClauseName(DVar.CKind)
9167  << getOpenMPClauseName(OMPC_reduction);
9168  ReportOriginalDSA(*this, DSAStack, D, DVar);
9169  continue;
9170  }
9171 
9172  // OpenMP [2.14.3.6, Restrictions, p.1]
9173  // A list item that appears in a reduction clause of a worksharing
9174  // construct must be shared in the parallel regions to which any of the
9175  // worksharing regions arising from the worksharing construct bind.
9176  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9177  if (isOpenMPWorksharingDirective(CurrDir) &&
9178  !isOpenMPParallelDirective(CurrDir)) {
9179  DVar = DSAStack->getImplicitDSA(D, true);
9180  if (DVar.CKind != OMPC_shared) {
9181  Diag(ELoc, diag::err_omp_required_access)
9182  << getOpenMPClauseName(OMPC_reduction)
9183  << getOpenMPClauseName(OMPC_shared);
9184  ReportOriginalDSA(*this, DSAStack, D, DVar);
9185  continue;
9186  }
9187  }
9188 
9189  // Try to find 'declare reduction' corresponding construct before using
9190  // builtin/overloaded operators.
9191  CXXCastPath BasePath;
9192  ExprResult DeclareReductionRef = buildDeclareReductionRef(
9193  *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec,
9194  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
9195  if (DeclareReductionRef.isInvalid())
9196  continue;
9197  if (CurContext->isDependentContext() &&
9198  (DeclareReductionRef.isUnset() ||
9199  isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
9200  Vars.push_back(RefExpr);
9201  Privates.push_back(nullptr);
9202  LHSs.push_back(nullptr);
9203  RHSs.push_back(nullptr);
9204  ReductionOps.push_back(DeclareReductionRef.get());
9205  continue;
9206  }
9207  if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
9208  // Not allowed reduction identifier is found.
9209  Diag(ReductionId.getLocStart(),
9210  diag::err_omp_unknown_reduction_identifier)
9211  << Type << ReductionIdRange;
9212  continue;
9213  }
9214 
9215  // OpenMP [2.14.3.6, reduction clause, Restrictions]
9216  // The type of a list item that appears in a reduction clause must be valid
9217  // for the reduction-identifier. For a max or min reduction in C, the type
9218  // of the list item must be an allowed arithmetic data type: char, int,
9219  // float, double, or _Bool, possibly modified with long, short, signed, or
9220  // unsigned. For a max or min reduction in C++, the type of the list item
9221  // must be an allowed arithmetic data type: char, wchar_t, int, float,
9222  // double, or bool, possibly modified with long, short, signed, or unsigned.
9223  if (DeclareReductionRef.isUnset()) {
9224  if ((BOK == BO_GT || BOK == BO_LT) &&
9225  !(Type->isScalarType() ||
9226  (getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
9227  Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
9228  << getLangOpts().CPlusPlus;
9229  if (!ASE && !OASE) {
9230  bool IsDecl = !VD ||
9231  VD->isThisDeclarationADefinition(Context) ==
9233  Diag(D->getLocation(),
9234  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9235  << D;
9236  }
9237  continue;
9238  }
9239  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
9240  !getLangOpts().CPlusPlus && Type->isFloatingType()) {
9241  Diag(ELoc, diag::err_omp_clause_floating_type_arg);
9242  if (!ASE && !OASE) {
9243  bool IsDecl = !VD ||
9244  VD->isThisDeclarationADefinition(Context) ==
9246  Diag(D->getLocation(),
9247  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9248  << D;
9249  }
9250  continue;
9251  }
9252  }
9253 
9254  Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
9255  auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs",
9256  D->hasAttrs() ? &D->getAttrs() : nullptr);
9257  auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(),
9258  D->hasAttrs() ? &D->getAttrs() : nullptr);
9259  auto PrivateTy = Type;
9260  if (OASE ||
9261  (!ASE &&
9263  // For arays/array sections only:
9264  // Create pseudo array type for private copy. The size for this array will
9265  // be generated during codegen.
9266  // For array subscripts or single variables Private Ty is the same as Type
9267  // (type of the variable or single array element).
9268  PrivateTy = Context.getVariableArrayType(
9269  Type, new (Context) OpaqueValueExpr(SourceLocation(),
9271  ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
9272  } else if (!ASE && !OASE &&
9274  PrivateTy = D->getType().getNonReferenceType();
9275  // Private copy.
9276  auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(),
9277  D->hasAttrs() ? &D->getAttrs() : nullptr);
9278  // Add initializer for private variable.
9279  Expr *Init = nullptr;
9280  auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc);
9281  auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc);
9282  if (DeclareReductionRef.isUsable()) {
9283  auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
9284  auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
9285  if (DRD->getInitializer()) {
9286  Init = DRDRef;
9287  RHSVD->setInit(DRDRef);
9288  RHSVD->setInitStyle(VarDecl::CallInit);
9289  }
9290  } else {
9291  switch (BOK) {
9292  case BO_Add:
9293  case BO_Xor:
9294  case BO_Or:
9295  case BO_LOr:
9296  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
9297  if (Type->isScalarType() || Type->isAnyComplexType())
9298  Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get();
9299  break;
9300  case BO_Mul:
9301  case BO_LAnd:
9302  if (Type->isScalarType() || Type->isAnyComplexType()) {
9303  // '*' and '&&' reduction ops - initializer is '1'.
9304  Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get();
9305  }
9306  break;
9307  case BO_And: {
9308  // '&' reduction op - initializer is '~0'.
9309  QualType OrigType = Type;
9310  if (auto *ComplexTy = OrigType->getAs<ComplexType>())
9311  Type = ComplexTy->getElementType();
9312  if (Type->isRealFloatingType()) {
9313  llvm::APFloat InitValue =
9314  llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
9315  /*isIEEE=*/true);
9316  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
9317  Type, ELoc);
9318  } else if (Type->isScalarType()) {
9319  auto Size = Context.getTypeSize(Type);
9320  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
9321  llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
9322  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
9323  }
9324  if (Init && OrigType->isAnyComplexType()) {
9325  // Init = 0xFFFF + 0xFFFFi;
9326  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
9327  Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
9328  }
9329  Type = OrigType;
9330  break;
9331  }
9332  case BO_LT:
9333  case BO_GT: {
9334  // 'min' reduction op - initializer is 'Largest representable number in
9335  // the reduction list item type'.
9336  // 'max' reduction op - initializer is 'Least representable number in
9337  // the reduction list item type'.
9338  if (Type->isIntegerType() || Type->isPointerType()) {
9339  bool IsSigned = Type->hasSignedIntegerRepresentation();
9340  auto Size = Context.getTypeSize(Type);
9341  QualType IntTy =
9342  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
9343  llvm::APInt InitValue =
9344  (BOK != BO_LT)
9345  ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
9346  : llvm::APInt::getMinValue(Size)
9347  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
9348  : llvm::APInt::getMaxValue(Size);
9349  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
9350  if (Type->isPointerType()) {
9351  // Cast to pointer type.
9354  SourceLocation(), Init);
9355  if (CastExpr.isInvalid())
9356  continue;
9357  Init = CastExpr.get();
9358  }
9359  } else if (Type->isRealFloatingType()) {
9360  llvm::APFloat InitValue = llvm::APFloat::getLargest(
9361  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
9362  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
9363  Type, ELoc);
9364  }
9365  break;
9366  }
9367  case BO_PtrMemD:
9368  case BO_PtrMemI:
9369  case BO_MulAssign:
9370  case BO_Div:
9371  case BO_Rem:
9372  case BO_Sub:
9373  case BO_Shl:
9374  case BO_Shr:
9375  case BO_LE:
9376  case BO_GE:
9377  case BO_EQ:
9378  case BO_NE:
9379  case BO_AndAssign:
9380  case BO_XorAssign:
9381  case BO_OrAssign:
9382  case BO_Assign:
9383  case BO_AddAssign:
9384  case BO_SubAssign:
9385  case BO_DivAssign:
9386  case BO_RemAssign:
9387  case BO_ShlAssign:
9388  case BO_ShrAssign:
9389  case BO_Comma:
9390  llvm_unreachable("Unexpected reduction operation");
9391  }
9392  }
9393  if (Init && DeclareReductionRef.isUnset()) {
9394  AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false,
9395  /*TypeMayContainAuto=*/false);
9396  } else if (!Init)
9397  ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false);
9398  if (RHSVD->isInvalidDecl())
9399  continue;
9400  if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
9401  Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
9402  << ReductionIdRange;
9403  bool IsDecl =
9404  !VD ||
9405  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9406  Diag(D->getLocation(),
9407  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9408  << D;
9409  continue;
9410  }
9411  // Store initializer for single element in private copy. Will be used during
9412  // codegen.
9413  PrivateVD->setInit(RHSVD->getInit());
9414  PrivateVD->setInitStyle(RHSVD->getInitStyle());
9415  auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc);
9416  ExprResult ReductionOp;
9417  if (DeclareReductionRef.isUsable()) {
9418  QualType RedTy = DeclareReductionRef.get()->getType();
9419  QualType PtrRedTy = Context.getPointerType(RedTy);
9420  ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
9421  ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
9422  if (!BasePath.empty()) {
9423  LHS = DefaultLvalueConversion(LHS.get());
9424  RHS = DefaultLvalueConversion(RHS.get());
9425  LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
9426  CK_UncheckedDerivedToBase, LHS.get(),
9427  &BasePath, LHS.get()->getValueKind());
9428  RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
9429  CK_UncheckedDerivedToBase, RHS.get(),
9430  &BasePath, RHS.get()->getValueKind());
9431  }
9433  QualType Params[] = {PtrRedTy, PtrRedTy};
9434  QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
9435  auto *OVE = new (Context) OpaqueValueExpr(
9437  DefaultLvalueConversion(DeclareReductionRef.get()).get());
9438  Expr *Args[] = {LHS.get(), RHS.get()};
9439  ReductionOp = new (Context)
9440  CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
9441  } else {
9442  ReductionOp = BuildBinOp(DSAStack->getCurScope(),
9443  ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
9444  if (ReductionOp.isUsable()) {
9445  if (BOK != BO_LT && BOK != BO_GT) {
9446  ReductionOp =
9447  BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
9448  BO_Assign, LHSDRE, ReductionOp.get());
9449  } else {
9450  auto *ConditionalOp = new (Context) ConditionalOperator(
9451  ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(),
9452  RHSDRE, Type, VK_LValue, OK_Ordinary);
9453  ReductionOp =
9454  BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
9455  BO_Assign, LHSDRE, ConditionalOp);
9456  }
9457  ReductionOp = ActOnFinishFullExpr(ReductionOp.get());
9458  }
9459  if (ReductionOp.isInvalid())
9460  continue;
9461  }
9462 
9463  DeclRefExpr *Ref = nullptr;
9464  Expr *VarsExpr = RefExpr->IgnoreParens();
9465  if (!VD && !CurContext->isDependentContext()) {
9466  if (ASE || OASE) {
9467  TransformExprToCaptures RebuildToCapture(*this, D);
9468  VarsExpr =
9469  RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
9470  Ref = RebuildToCapture.getCapturedExpr();
9471  } else {
9472  VarsExpr = Ref =
9473  buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9474  }
9475  if (!IsOpenMPCapturedDecl(D)) {
9476  ExprCaptures.push_back(Ref->getDecl());
9477  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
9478  ExprResult RefRes = DefaultLvalueConversion(Ref);
9479  if (!RefRes.isUsable())
9480  continue;
9481  ExprResult PostUpdateRes =
9482  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
9483  SimpleRefExpr, RefRes.get());
9484  if (!PostUpdateRes.isUsable())
9485  continue;
9486  ExprPostUpdates.push_back(
9487  IgnoredValueConversions(PostUpdateRes.get()).get());
9488  }
9489  }
9490  }
9491  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
9492  Vars.push_back(VarsExpr);
9493  Privates.push_back(PrivateDRE);
9494  LHSs.push_back(LHSDRE);
9495  RHSs.push_back(RHSDRE);
9496  ReductionOps.push_back(ReductionOp.get());
9497  }
9498 
9499  if (Vars.empty())
9500  return nullptr;
9501 
9503  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
9504  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates,
9505  LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures),
9506  buildPostUpdate(*this, ExprPostUpdates));
9507 }
9508 
9510  SourceLocation LinLoc) {
9511  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
9512  LinKind == OMPC_LINEAR_unknown) {
9513  Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
9514  return true;
9515  }
9516  return false;
9517 }
9518 
9520  OpenMPLinearClauseKind LinKind,
9521  QualType Type) {
9522  auto *VD = dyn_cast_or_null<VarDecl>(D);
9523  // A variable must not have an incomplete type or a reference type.
9524  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
9525  return true;
9526  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
9527  !Type->isReferenceType()) {
9528  Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
9529  << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
9530  return true;
9531  }
9532  Type = Type.getNonReferenceType();
9533 
9534  // A list item must not be const-qualified.
9535  if (Type.isConstant(Context)) {
9536  Diag(ELoc, diag::err_omp_const_variable)
9537  << getOpenMPClauseName(OMPC_linear);
9538  if (D) {
9539  bool IsDecl =
9540  !VD ||
9541  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9542  Diag(D->getLocation(),
9543  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9544  << D;
9545  }
9546  return true;
9547  }
9548 
9549  // A list item must be of integral or pointer type.
9550  Type = Type.getUnqualifiedType().getCanonicalType();
9551  const auto *Ty = Type.getTypePtrOrNull();
9552  if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
9553  !Ty->isPointerType())) {
9554  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
9555  if (D) {
9556  bool IsDecl =
9557  !VD ||
9558  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9559  Diag(D->getLocation(),
9560  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9561  << D;
9562  }
9563  return true;
9564  }
9565  return false;
9566 }
9567 
9569  ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
9570  SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
9575  SmallVector<Decl *, 4> ExprCaptures;
9576  SmallVector<Expr *, 4> ExprPostUpdates;
9577  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
9578  LinKind = OMPC_LINEAR_val;
9579  for (auto &RefExpr : VarList) {
9580  assert(RefExpr && "NULL expr in OpenMP linear clause.");
9581  SourceLocation ELoc;
9582  SourceRange ERange;
9583  Expr *SimpleRefExpr = RefExpr;
9584  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
9585  /*AllowArraySection=*/false);
9586  if (Res.second) {
9587  // It will be analyzed later.
9588  Vars.push_back(RefExpr);
9589  Privates.push_back(nullptr);
9590  Inits.push_back(nullptr);
9591  }
9592  ValueDecl *D = Res.first;
9593  if (!D)
9594  continue;
9595 
9596  QualType Type = D->getType();
9597  auto *VD = dyn_cast<VarDecl>(D);
9598 
9599  // OpenMP [2.14.3.7, linear clause]
9600  // A list-item cannot appear in more than one linear clause.
9601  // A list-item that appears in a linear clause cannot appear in any
9602  // other data-sharing attribute clause.
9603  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9604  if (DVar.RefExpr) {
9605  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9606  << getOpenMPClauseName(OMPC_linear);
9607  ReportOriginalDSA(*this, DSAStack, D, DVar);
9608  continue;
9609  }
9610 
9611  if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
9612  continue;
9614 
9615  // Build private copy of original var.
9616  auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(),
9617  D->hasAttrs() ? &D->getAttrs() : nullptr);
9618  auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
9619  // Build var to save initial value.
9620  VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
9621  Expr *InitExpr;
9622  DeclRefExpr *Ref = nullptr;
9623  if (!VD && !CurContext->isDependentContext()) {
9624  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9625  if (!IsOpenMPCapturedDecl(D)) {
9626  ExprCaptures.push_back(Ref->getDecl());
9627  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
9628  ExprResult RefRes = DefaultLvalueConversion(Ref);
9629  if (!RefRes.isUsable())
9630  continue;
9631  ExprResult PostUpdateRes =
9632  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
9633  SimpleRefExpr, RefRes.get());
9634  if (!PostUpdateRes.isUsable())
9635  continue;
9636  ExprPostUpdates.push_back(
9637  IgnoredValueConversions(PostUpdateRes.get()).get());
9638  }
9639  }
9640  }
9641  if (LinKind == OMPC_LINEAR_uval)
9642  InitExpr = VD ? VD->getInit() : SimpleRefExpr;
9643  else
9644  InitExpr = VD ? SimpleRefExpr : Ref;
9645  AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
9646  /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
9647  auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
9648 
9649  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
9650  Vars.push_back((VD || CurContext->isDependentContext())
9651  ? RefExpr->IgnoreParens()
9652  : Ref);
9653  Privates.push_back(PrivateRef);
9654  Inits.push_back(InitRef);
9655  }
9656 
9657  if (Vars.empty())
9658  return nullptr;
9659 
9660  Expr *StepExpr = Step;
9661  Expr *CalcStepExpr = nullptr;
9662  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
9663  !Step->isInstantiationDependent() &&
9665  SourceLocation StepLoc = Step->getLocStart();
9667  if (Val.isInvalid())
9668  return nullptr;
9669  StepExpr = Val.get();
9670 
9671  // Build var to save the step value.
9672  VarDecl *SaveVar =
9673  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
9674  ExprResult SaveRef =
9675  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
9677  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
9678  CalcStep = ActOnFinishFullExpr(CalcStep.get());
9679 
9680  // Warn about zero linear step (it would be probably better specified as
9681  // making corresponding variables 'const').
9682  llvm::APSInt Result;
9683  bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
9684  if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
9685  Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
9686  << (Vars.size() > 1);
9687  if (!IsConstant && CalcStep.isUsable()) {
9688  // Calculate the step beforehand instead of doing this on each iteration.
9689  // (This is not used if the number of iterations may be kfold-ed).
9690  CalcStepExpr = CalcStep.get();
9691  }
9692  }
9693 
9694  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
9695  ColonLoc, EndLoc, Vars, Privates, Inits,
9696  StepExpr, CalcStepExpr,
9697  buildPreInits(Context, ExprCaptures),
9698  buildPostUpdate(*this, ExprPostUpdates));
9699 }
9700 
9702  Expr *NumIterations, Sema &SemaRef,
9703  Scope *S, DSAStackTy *Stack) {
9704  // Walk the vars and build update/final expressions for the CodeGen.
9707  Expr *Step = Clause.getStep();
9708  Expr *CalcStep = Clause.getCalcStep();
9709  // OpenMP [2.14.3.7, linear clause]
9710  // If linear-step is not specified it is assumed to be 1.
9711  if (Step == nullptr)
9712  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9713  else if (CalcStep) {
9714  Step = cast<BinaryOperator>(CalcStep)->getLHS();
9715  }
9716  bool HasErrors = false;
9717  auto CurInit = Clause.inits().begin();
9718  auto CurPrivate = Clause.privates().begin();
9719  auto LinKind = Clause.getModifier();
9720  for (auto &RefExpr : Clause.varlists()) {
9721  SourceLocation ELoc;
9722  SourceRange ERange;
9723  Expr *SimpleRefExpr = RefExpr;
9724  auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
9725  /*AllowArraySection=*/false);
9726  ValueDecl *D = Res.first;
9727  if (Res.second || !D) {
9728  Updates.push_back(nullptr);
9729  Finals.push_back(nullptr);
9730  HasErrors = true;
9731  continue;
9732  }
9733  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) {
9734  D = cast<MemberExpr>(CED->getInit()->IgnoreParenImpCasts())
9735  ->getMemberDecl();
9736  }
9737  auto &&Info = Stack->isLoopControlVariable(D);
9738  Expr *InitExpr = *CurInit;
9739 
9740  // Build privatized reference to the current linear var.
9741  auto DE = cast<DeclRefExpr>(SimpleRefExpr);
9742  Expr *CapturedRef;
9743  if (LinKind == OMPC_LINEAR_uval)
9744  CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
9745  else
9746  CapturedRef =
9747  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
9748  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
9749  /*RefersToCapture=*/true);
9750 
9751  // Build update: Var = InitExpr + IV * Step
9752  ExprResult Update;
9753  if (!Info.first) {
9754  Update =
9755  BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
9756  InitExpr, IV, Step, /* Subtract */ false);
9757  } else
9758  Update = *CurPrivate;
9759  Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
9760  /*DiscardedValue=*/true);
9761 
9762  // Build final: Var = InitExpr + NumIterations * Step
9763  ExprResult Final;
9764  if (!Info.first) {
9765  Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
9766  InitExpr, NumIterations, Step,
9767  /* Subtract */ false);
9768  } else
9769  Final = *CurPrivate;
9770  Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
9771  /*DiscardedValue=*/true);
9772 
9773  if (!Update.isUsable() || !Final.isUsable()) {
9774  Updates.push_back(nullptr);
9775  Finals.push_back(nullptr);
9776  HasErrors = true;
9777  } else {
9778  Updates.push_back(Update.get());
9779  Finals.push_back(Final.get());
9780  }
9781  ++CurInit;
9782  ++CurPrivate;
9783  }
9784  Clause.setUpdates(Updates);
9785  Clause.setFinals(Finals);
9786  return HasErrors;
9787 }
9788 
9790  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
9792 
9794  for (auto &RefExpr : VarList) {
9795  assert(RefExpr && "NULL expr in OpenMP linear clause.");
9796  SourceLocation ELoc;
9797  SourceRange ERange;
9798  Expr *SimpleRefExpr = RefExpr;
9799  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
9800  /*AllowArraySection=*/false);
9801  if (Res.second) {
9802  // It will be analyzed later.
9803  Vars.push_back(RefExpr);
9804  }
9805  ValueDecl *D = Res.first;
9806  if (!D)
9807  continue;
9808 
9809  QualType QType = D->getType();
9810  auto *VD = dyn_cast<VarDecl>(D);
9811 
9812  // OpenMP [2.8.1, simd construct, Restrictions]
9813  // The type of list items appearing in the aligned clause must be
9814  // array, pointer, reference to array, or reference to pointer.
9816  const Type *Ty = QType.getTypePtrOrNull();
9817  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
9818  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
9819  << QType << getLangOpts().CPlusPlus << ERange;
9820  bool IsDecl =
9821  !VD ||
9822  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9823  Diag(D->getLocation(),
9824  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9825  << D;
9826  continue;
9827  }
9828 
9829  // OpenMP [2.8.1, simd construct, Restrictions]
9830  // A list-item cannot appear in more than one aligned clause.
9831  if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
9832  Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
9833  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
9834  << getOpenMPClauseName(OMPC_aligned);
9835  continue;
9836  }
9837 
9838  DeclRefExpr *Ref = nullptr;
9839  if (!VD && IsOpenMPCapturedDecl(D))
9840  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9841  Vars.push_back(DefaultFunctionArrayConversion(
9842  (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
9843  .get());
9844  }
9845 
9846  // OpenMP [2.8.1, simd construct, Description]
9847  // The parameter of the aligned clause, alignment, must be a constant
9848  // positive integer expression.
9849  // If no optional parameter is specified, implementation-defined default
9850  // alignments for SIMD instructions on the target platforms are assumed.
9851  if (Alignment != nullptr) {
9852  ExprResult AlignResult =
9853  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
9854  if (AlignResult.isInvalid())
9855  return nullptr;
9856  Alignment = AlignResult.get();
9857  }
9858  if (Vars.empty())
9859  return nullptr;
9860 
9861  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
9862  EndLoc, Vars, Alignment);
9863 }
9864 
9866  SourceLocation StartLoc,
9867  SourceLocation LParenLoc,
9868  SourceLocation EndLoc) {
9870  SmallVector<Expr *, 8> SrcExprs;
9871  SmallVector<Expr *, 8> DstExprs;
9872  SmallVector<Expr *, 8> AssignmentOps;
9873  for (auto &RefExpr : VarList) {
9874  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
9875  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
9876  // It will be analyzed later.
9877  Vars.push_back(RefExpr);
9878  SrcExprs.push_back(nullptr);
9879  DstExprs.push_back(nullptr);
9880  AssignmentOps.push_back(nullptr);
9881  continue;
9882  }
9883 
9884  SourceLocation ELoc = RefExpr->getExprLoc();
9885  // OpenMP [2.1, C/C++]
9886  // A list item is a variable name.
9887  // OpenMP [2.14.4.1, Restrictions, p.1]
9888  // A list item that appears in a copyin clause must be threadprivate.
9889  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
9890  if (!DE || !isa<VarDecl>(DE->getDecl())) {
9891  Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
9892  << 0 << RefExpr->getSourceRange();
9893  continue;
9894  }
9895 
9896  Decl *D = DE->getDecl();
9897  VarDecl *VD = cast<VarDecl>(D);
9898 
9899  QualType Type = VD->getType();
9900  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
9901  // It will be analyzed later.
9902  Vars.push_back(DE);
9903  SrcExprs.push_back(nullptr);
9904  DstExprs.push_back(nullptr);
9905  AssignmentOps.push_back(nullptr);
9906  continue;
9907  }
9908 
9909  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
9910  // A list item that appears in a copyin clause must be threadprivate.
9911  if (!DSAStack->isThreadPrivate(VD)) {
9912  Diag(ELoc, diag::err_omp_required_access)
9913  << getOpenMPClauseName(OMPC_copyin)
9914  << getOpenMPDirectiveName(OMPD_threadprivate);
9915  continue;
9916  }
9917 
9918  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
9919  // A variable of class type (or array thereof) that appears in a
9920  // copyin clause requires an accessible, unambiguous copy assignment
9921  // operator for the class type.
9922  auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
9923  auto *SrcVD =
9924  buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(),
9925  ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
9926  auto *PseudoSrcExpr = buildDeclRefExpr(
9927  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
9928  auto *DstVD =
9929  buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst",
9930  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
9931  auto *PseudoDstExpr =
9932  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
9933  // For arrays generate assignment operation for single element and replace
9934  // it by the original array element in CodeGen.
9935  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
9936  PseudoDstExpr, PseudoSrcExpr);
9937  if (AssignmentOp.isInvalid())
9938  continue;
9939  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
9940  /*DiscardedValue=*/true);
9941  if (AssignmentOp.isInvalid())
9942  continue;
9943 
9944  DSAStack->addDSA(VD, DE, OMPC_copyin);
9945  Vars.push_back(DE);
9946  SrcExprs.push_back(PseudoSrcExpr);
9947  DstExprs.push_back(PseudoDstExpr);
9948  AssignmentOps.push_back(AssignmentOp.get());
9949  }
9950 
9951  if (Vars.empty())
9952  return nullptr;
9953 
9954  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9955  SrcExprs, DstExprs, AssignmentOps);
9956 }
9957 
9959  SourceLocation StartLoc,
9960  SourceLocation LParenLoc,
9961  SourceLocation EndLoc) {
9963  SmallVector<Expr *, 8> SrcExprs;
9964  SmallVector<Expr *, 8> DstExprs;
9965  SmallVector<Expr *, 8> AssignmentOps;
9966  for (auto &RefExpr : VarList) {
9967  assert(RefExpr && "NULL expr in OpenMP linear clause.");
9968  SourceLocation ELoc;
9969  SourceRange ERange;
9970  Expr *SimpleRefExpr = RefExpr;
9971  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
9972  /*AllowArraySection=*/false);
9973  if (Res.second) {
9974  // It will be analyzed later.
9975  Vars.push_back(RefExpr);
9976  SrcExprs.push_back(nullptr);
9977  DstExprs.push_back(nullptr);
9978  AssignmentOps.push_back(nullptr);
9979  }
9980  ValueDecl *D = Res.first;
9981  if (!D)
9982  continue;
9983 
9984  QualType Type = D->getType();
9985  auto *VD = dyn_cast<VarDecl>(D);
9986 
9987  // OpenMP [2.14.4.2, Restrictions, p.2]
9988  // A list item that appears in a copyprivate clause may not appear in a
9989  // private or firstprivate clause on the single construct.
9990  if (!VD || !DSAStack->isThreadPrivate(VD)) {
9991  auto DVar = DSAStack->getTopDSA(D, false);
9992  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
9993  DVar.RefExpr) {
9994  Diag(ELoc, diag::err_omp_wrong_dsa)
9995  << getOpenMPClauseName(DVar.CKind)
9996  << getOpenMPClauseName(OMPC_copyprivate);
9997  ReportOriginalDSA(*this, DSAStack, D, DVar);
9998  continue;
9999  }
10000 
10001  // OpenMP [2.11.4.2, Restrictions, p.1]
10002  // All list items that appear in a copyprivate clause must be either
10003  // threadprivate or private in the enclosing context.
10004  if (DVar.CKind == OMPC_unknown) {
10005  DVar = DSAStack->getImplicitDSA(D, false);
10006  if (DVar.CKind == OMPC_shared) {
10007  Diag(ELoc, diag::err_omp_required_access)
10008  << getOpenMPClauseName(OMPC_copyprivate)
10009  << "threadprivate or private in the enclosing context";
10010  ReportOriginalDSA(*this, DSAStack, D, DVar);
10011  continue;
10012  }
10013  }
10014  }
10015 
10016  // Variably modified types are not supported.
10017  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
10018  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10019  << getOpenMPClauseName(OMPC_copyprivate) << Type
10020  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
10021  bool IsDecl =
10022  !VD ||
10023  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10024  Diag(D->getLocation(),
10025  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10026  << D;
10027  continue;
10028  }
10029 
10030  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
10031  // A variable of class type (or array thereof) that appears in a
10032  // copyin clause requires an accessible, unambiguous copy assignment
10033  // operator for the class type.
10035  .getUnqualifiedType();
10036  auto *SrcVD =
10037  buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src",
10038  D->hasAttrs() ? &D->getAttrs() : nullptr);
10039  auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
10040  auto *DstVD =
10041  buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst",
10042  D->hasAttrs() ? &D->getAttrs() : nullptr);
10043  auto *PseudoDstExpr =
10044  buildDeclRefExpr(*this, DstVD, Type, ELoc);
10045  auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
10046  PseudoDstExpr, PseudoSrcExpr);
10047  if (AssignmentOp.isInvalid())
10048  continue;
10049  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
10050  /*DiscardedValue=*/true);
10051  if (AssignmentOp.isInvalid())
10052  continue;
10053 
10054  // No need to mark vars as copyprivate, they are already threadprivate or
10055  // implicitly private.
10056  assert(VD || IsOpenMPCapturedDecl(D));
10057  Vars.push_back(
10058  VD ? RefExpr->IgnoreParens()
10059  : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
10060  SrcExprs.push_back(PseudoSrcExpr);
10061  DstExprs.push_back(PseudoDstExpr);
10062  AssignmentOps.push_back(AssignmentOp.get());
10063  }
10064 
10065  if (Vars.empty())
10066  return nullptr;
10067 
10068  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10069  Vars, SrcExprs, DstExprs, AssignmentOps);
10070 }
10071 
10073  SourceLocation StartLoc,
10074  SourceLocation LParenLoc,
10075  SourceLocation EndLoc) {
10076  if (VarList.empty())
10077  return nullptr;
10078 
10079  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
10080 }
10081 
10082 OMPClause *
10085  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
10086  SourceLocation LParenLoc, SourceLocation EndLoc) {
10087  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
10088  DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
10089  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
10090  << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
10091  return nullptr;
10092  }
10093  if (DSAStack->getCurrentDirective() != OMPD_ordered &&
10094  (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
10095  DepKind == OMPC_DEPEND_sink)) {
10096  unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
10097  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
10098  << getListOfPossibleValues(OMPC_depend, /*First=*/0,
10099  /*Last=*/OMPC_DEPEND_unknown, Except)
10100  << getOpenMPClauseName(OMPC_depend);
10101  return nullptr;
10102  }
10105  llvm::APSInt DepCounter(/*BitWidth=*/32);
10106  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
10107  if (DepKind == OMPC_DEPEND_sink) {
10108  if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) {
10109  TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
10110  TotalDepCount.setIsUnsigned(/*Val=*/true);
10111  }
10112  }
10113  if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
10114  DSAStack->getParentOrderedRegionParam()) {
10115  for (auto &RefExpr : VarList) {
10116  assert(RefExpr && "NULL expr in OpenMP shared clause.");
10117  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
10118  // It will be analyzed later.
10119  Vars.push_back(RefExpr);
10120  continue;
10121  }
10122 
10123  SourceLocation ELoc = RefExpr->getExprLoc();
10124  auto *SimpleExpr = RefExpr->IgnoreParenCasts();
10125  if (DepKind == OMPC_DEPEND_sink) {
10126  if (DepCounter >= TotalDepCount) {
10127  Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
10128  continue;
10129  }
10130  ++DepCounter;
10131  // OpenMP [2.13.9, Summary]
10132  // depend(dependence-type : vec), where dependence-type is:
10133  // 'sink' and where vec is the iteration vector, which has the form:
10134  // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
10135  // where n is the value specified by the ordered clause in the loop
10136  // directive, xi denotes the loop iteration variable of the i-th nested
10137  // loop associated with the loop directive, and di is a constant
10138  // non-negative integer.
10139  if (CurContext->isDependentContext()) {
10140  // It will be analyzed later.
10141  Vars.push_back(RefExpr);
10142  continue;
10143  }
10144  SimpleExpr = SimpleExpr->IgnoreImplicit();
10146  SourceLocation OOLoc;
10147  Expr *LHS = SimpleExpr;
10148  Expr *RHS = nullptr;
10149  if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
10150  OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
10151  OOLoc = BO->getOperatorLoc();
10152  LHS = BO->getLHS()->IgnoreParenImpCasts();
10153  RHS = BO->getRHS()->IgnoreParenImpCasts();
10154  } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
10155  OOK = OCE->getOperator();
10156  OOLoc = OCE->getOperatorLoc();
10157  LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
10158  RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
10159  } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
10160  OOK = MCE->getMethodDecl()
10161  ->getNameInfo()
10162  .getName()
10163  .getCXXOverloadedOperator();
10164  OOLoc = MCE->getCallee()->getExprLoc();
10165  LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
10166  RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
10167  }
10168  SourceLocation ELoc;
10169  SourceRange ERange;
10170  auto Res = getPrivateItem(*this, LHS, ELoc, ERange,
10171  /*AllowArraySection=*/false);
10172  if (Res.second) {
10173  // It will be analyzed later.
10174  Vars.push_back(RefExpr);
10175  }
10176  ValueDecl *D = Res.first;
10177  if (!D)
10178  continue;
10179 
10180  if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
10181  Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
10182  continue;
10183  }
10184  if (RHS) {
10185  ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
10186  RHS, OMPC_depend, /*StrictlyPositive=*/false);
10187  if (RHSRes.isInvalid())
10188  continue;
10189  }
10190  if (!CurContext->isDependentContext() &&
10191  DSAStack->getParentOrderedRegionParam() &&
10192  DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
10193  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
10194  << DSAStack->getParentLoopControlVariable(
10195  DepCounter.getZExtValue());
10196  continue;
10197  }
10198  OpsOffs.push_back({RHS, OOK});
10199  } else {
10200  // OpenMP [2.11.1.1, Restrictions, p.3]
10201  // A variable that is part of another variable (such as a field of a
10202  // structure) but is not an array element or an array section cannot
10203  // appear in a depend clause.
10204  auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
10205  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
10206  auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
10207  if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
10208  (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) ||
10209  (ASE &&
10210  !ASE->getBase()
10211  ->getType()
10212  .getNonReferenceType()
10213  ->isPointerType() &&
10214  !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
10215  Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item)
10216  << 0 << RefExpr->getSourceRange();
10217  continue;
10218  }
10219  }
10220  Vars.push_back(RefExpr->IgnoreParenImpCasts());
10221  }
10222 
10223  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
10224  TotalDepCount > VarList.size() &&
10225  DSAStack->getParentOrderedRegionParam()) {
10226  Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
10227  << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
10228  }
10229  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
10230  Vars.empty())
10231  return nullptr;
10232  }
10233  auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10234  DepKind, DepLoc, ColonLoc, Vars);
10235  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source)
10236  DSAStack->addDoacrossDependClause(C, OpsOffs);
10237  return C;
10238 }
10239 
10241  SourceLocation LParenLoc,
10242  SourceLocation EndLoc) {
10243  Expr *ValExpr = Device;
10244 
10245  // OpenMP [2.9.1, Restrictions]
10246  // The device expression must evaluate to a non-negative integer value.
10247  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
10248  /*StrictlyPositive=*/false))
10249  return nullptr;
10250 
10251  return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc);
10252 }
10253 
10254 static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc,
10255  DSAStackTy *Stack, CXXRecordDecl *RD) {
10256  if (!RD || RD->isInvalidDecl())
10257  return true;
10258 
10259  if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
10260  if (auto *CTD = CTSD->getSpecializedTemplate())
10261  RD = CTD->getTemplatedDecl();
10262  auto QTy = SemaRef.Context.getRecordType(RD);
10263  if (RD->isDynamicClass()) {
10264  SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
10265  SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target);
10266  return false;
10267  }
10268  auto *DC = RD;
10269  bool IsCorrect = true;
10270  for (auto *I : DC->decls()) {
10271  if (I) {
10272  if (auto *MD = dyn_cast<CXXMethodDecl>(I)) {
10273  if (MD->isStatic()) {
10274  SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
10275  SemaRef.Diag(MD->getLocation(),
10276  diag::note_omp_static_member_in_target);
10277  IsCorrect = false;
10278  }
10279  } else if (auto *VD = dyn_cast<VarDecl>(I)) {
10280  if (VD->isStaticDataMember()) {
10281  SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
10282  SemaRef.Diag(VD->getLocation(),
10283  diag::note_omp_static_member_in_target);
10284  IsCorrect = false;
10285  }
10286  }
10287  }
10288  }
10289 
10290  for (auto &I : RD->bases()) {
10291  if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack,
10292  I.getType()->getAsCXXRecordDecl()))
10293  IsCorrect = false;
10294  }
10295  return IsCorrect;
10296 }
10297 
10298 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
10299  DSAStackTy *Stack, QualType QTy) {
10300  NamedDecl *ND;
10301  if (QTy->isIncompleteType(&ND)) {
10302  SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
10303  return false;
10304  } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) {
10305  if (!RD->isInvalidDecl() &&
10306  !IsCXXRecordForMappable(SemaRef, SL, Stack, RD))
10307  return false;
10308  }
10309  return true;
10310 }
10311 
10312 /// \brief Return true if it can be proven that the provided array expression
10313 /// (array section or array subscript) does NOT specify the whole size of the
10314 /// array whose base type is \a BaseQTy.
10316  const Expr *E,
10317  QualType BaseQTy) {
10318  auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
10319 
10320  // If this is an array subscript, it refers to the whole size if the size of
10321  // the dimension is constant and equals 1. Also, an array section assumes the
10322  // format of an array subscript if no colon is used.
10323  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
10324  if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
10325  return ATy->getSize().getSExtValue() != 1;
10326  // Size can't be evaluated statically.
10327  return false;
10328  }
10329 
10330  assert(OASE && "Expecting array section if not an array subscript.");
10331  auto *LowerBound = OASE->getLowerBound();
10332  auto *Length = OASE->getLength();
10333 
10334  // If there is a lower bound that does not evaluates to zero, we are not
10335  // convering the whole dimension.
10336  if (LowerBound) {
10337  llvm::APSInt ConstLowerBound;
10338  if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext()))
10339  return false; // Can't get the integer value as a constant.
10340  if (ConstLowerBound.getSExtValue())
10341  return true;
10342  }
10343 
10344  // If we don't have a length we covering the whole dimension.
10345  if (!Length)
10346  return false;
10347 
10348  // If the base is a pointer, we don't have a way to get the size of the
10349  // pointee.
10350  if (BaseQTy->isPointerType())
10351  return false;
10352 
10353  // We can only check if the length is the same as the size of the dimension
10354  // if we have a constant array.
10355  auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
10356  if (!CATy)
10357  return false;
10358 
10359  llvm::APSInt ConstLength;
10360  if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
10361  return false; // Can't get the integer value as a constant.
10362 
10363  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
10364 }
10365 
10366 // Return true if it can be proven that the provided array expression (array
10367 // section or array subscript) does NOT specify a single element of the array
10368 // whose base type is \a BaseQTy.
10370  const Expr *E,
10371  QualType BaseQTy) {
10372  auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
10373 
10374  // An array subscript always refer to a single element. Also, an array section
10375  // assumes the format of an array subscript if no colon is used.
10376  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
10377  return false;
10378 
10379  assert(OASE && "Expecting array section if not an array subscript.");
10380  auto *Length = OASE->getLength();
10381 
10382  // If we don't have a length we have to check if the array has unitary size
10383  // for this dimension. Also, we should always expect a length if the base type
10384  // is pointer.
10385  if (!Length) {
10386  if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
10387  return ATy->getSize().getSExtValue() != 1;
10388  // We cannot assume anything.
10389  return false;
10390  }
10391 
10392  // Check if the length evaluates to 1.
10393  llvm::APSInt ConstLength;
10394  if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
10395  return false; // Can't get the integer value as a constant.
10396 
10397  return ConstLength.getSExtValue() != 1;
10398 }
10399 
10400 // Return the expression of the base of the mappable expression or null if it
10401 // cannot be determined and do all the necessary checks to see if the expression
10402 // is valid as a standalone mappable expression. In the process, record all the
10403 // components of the expression.
10405  Sema &SemaRef, Expr *E,
10407  OpenMPClauseKind CKind) {
10408  SourceLocation ELoc = E->getExprLoc();
10409  SourceRange ERange = E->getSourceRange();
10410 
10411  // The base of elements of list in a map clause have to be either:
10412  // - a reference to variable or field.
10413  // - a member expression.
10414  // - an array expression.
10415  //
10416  // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
10417  // reference to 'r'.
10418  //
10419  // If we have:
10420  //
10421  // struct SS {
10422  // Bla S;
10423  // foo() {
10424  // #pragma omp target map (S.Arr[:12]);
10425  // }
10426  // }
10427  //
10428  // We want to retrieve the member expression 'this->S';
10429 
10430  Expr *RelevantExpr = nullptr;
10431 
10432  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
10433  // If a list item is an array section, it must specify contiguous storage.
10434  //
10435  // For this restriction it is sufficient that we make sure only references
10436  // to variables or fields and array expressions, and that no array sections
10437  // exist except in the rightmost expression (unless they cover the whole
10438  // dimension of the array). E.g. these would be invalid:
10439  //
10440  // r.ArrS[3:5].Arr[6:7]
10441  //
10442  // r.ArrS[3:5].x
10443  //
10444  // but these would be valid:
10445  // r.ArrS[3].Arr[6:7]
10446  //
10447  // r.ArrS[3].x
10448 
10449  bool AllowUnitySizeArraySection = true;
10450  bool AllowWholeSizeArraySection = true;
10451 
10452  while (!RelevantExpr) {
10453  E = E->IgnoreParenImpCasts();
10454 
10455  if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
10456  if (!isa<VarDecl>(CurE->getDecl()))
10457  break;
10458 
10459  RelevantExpr = CurE;
10460 
10461  // If we got a reference to a declaration, we should not expect any array
10462  // section before that.
10463  AllowUnitySizeArraySection = false;
10464  AllowWholeSizeArraySection = false;
10465 
10466  // Record the component.
10467  CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent(
10468  CurE, CurE->getDecl()));
10469  continue;
10470  }
10471 
10472  if (auto *CurE = dyn_cast<MemberExpr>(E)) {
10473  auto *BaseE = CurE->getBase()->IgnoreParenImpCasts();
10474 
10475  if (isa<CXXThisExpr>(BaseE))
10476  // We found a base expression: this->Val.
10477  RelevantExpr = CurE;
10478  else
10479  E = BaseE;
10480 
10481  if (!isa<FieldDecl>(CurE->getMemberDecl())) {
10482  SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
10483  << CurE->getSourceRange();
10484  break;
10485  }
10486 
10487  auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
10488 
10489  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
10490  // A bit-field cannot appear in a map clause.
10491  //
10492  if (FD->isBitField()) {
10493  SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
10494  << CurE->getSourceRange() << getOpenMPClauseName(CKind);
10495  break;
10496  }
10497 
10498  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
10499  // If the type of a list item is a reference to a type T then the type
10500  // will be considered to be T for all purposes of this clause.
10501  QualType CurType = BaseE->getType().getNonReferenceType();
10502 
10503  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
10504  // A list item cannot be a variable that is a member of a structure with
10505  // a union type.
10506  //
10507  if (auto *RT = CurType->getAs<RecordType>())
10508  if (RT->isUnionType()) {
10509  SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
10510  << CurE->getSourceRange();
10511  break;
10512  }
10513 
10514  // If we got a member expression, we should not expect any array section
10515  // before that:
10516  //
10517  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
10518  // If a list item is an element of a structure, only the rightmost symbol
10519  // of the variable reference can be an array section.
10520  //
10521  AllowUnitySizeArraySection = false;
10522  AllowWholeSizeArraySection = false;
10523 
10524  // Record the component.
10525  CurComponents.push_back(
10527  continue;
10528  }
10529 
10530  if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
10531  E = CurE->getBase()->IgnoreParenImpCasts();
10532 
10533  if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
10534  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
10535  << 0 << CurE->getSourceRange();
10536  break;
10537  }
10538 
10539  // If we got an array subscript that express the whole dimension we
10540  // can have any array expressions before. If it only expressing part of
10541  // the dimension, we can only have unitary-size array expressions.
10543  E->getType()))
10544  AllowWholeSizeArraySection = false;
10545 
10546  // Record the component - we don't have any declaration associated.
10547  CurComponents.push_back(
10549  continue;
10550  }
10551 
10552  if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
10553  E = CurE->getBase()->IgnoreParenImpCasts();
10554 
10555  auto CurType =
10557 
10558  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
10559  // If the type of a list item is a reference to a type T then the type
10560  // will be considered to be T for all purposes of this clause.
10561  if (CurType->isReferenceType())
10562  CurType = CurType->getPointeeType();
10563 
10564  bool IsPointer = CurType->isAnyPointerType();
10565 
10566  if (!IsPointer && !CurType->isArrayType()) {
10567  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
10568  << 0 << CurE->getSourceRange();
10569  break;
10570  }
10571 
10572  bool NotWhole =
10573  CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
10574  bool NotUnity =
10575  CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
10576 
10577  if (AllowWholeSizeArraySection && AllowUnitySizeArraySection) {
10578  // Any array section is currently allowed.
10579  //
10580  // If this array section refers to the whole dimension we can still
10581  // accept other array sections before this one, except if the base is a
10582  // pointer. Otherwise, only unitary sections are accepted.
10583  if (NotWhole || IsPointer)
10584  AllowWholeSizeArraySection = false;
10585  } else if ((AllowUnitySizeArraySection && NotUnity) ||
10586  (AllowWholeSizeArraySection && NotWhole)) {
10587  // A unity or whole array section is not allowed and that is not
10588  // compatible with the properties of the current array section.
10589  SemaRef.Diag(
10590  ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
10591  << CurE->getSourceRange();
10592  break;
10593  }
10594 
10595  // Record the component - we don't have any declaration associated.
10596  CurComponents.push_back(
10598  continue;
10599  }
10600 
10601  // If nothing else worked, this is not a valid map clause expression.
10602  SemaRef.Diag(ELoc,
10603  diag::err_omp_expected_named_var_member_or_array_expression)
10604  << ERange;
10605  break;
10606  }
10607 
10608  return RelevantExpr;
10609 }
10610 
10611 // Return true if expression E associated with value VD has conflicts with other
10612 // map information.
10613 static bool CheckMapConflicts(
10614  Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E,
10615  bool CurrentRegionOnly,
10617  OpenMPClauseKind CKind) {
10618  assert(VD && E);
10619  SourceLocation ELoc = E->getExprLoc();
10620  SourceRange ERange = E->getSourceRange();
10621 
10622  // In order to easily check the conflicts we need to match each component of
10623  // the expression under test with the components of the expressions that are
10624  // already in the stack.
10625 
10626  assert(!CurComponents.empty() && "Map clause expression with no components!");
10627  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
10628  "Map clause expression with unexpected base!");
10629 
10630  // Variables to help detecting enclosing problems in data environment nests.
10631  bool IsEnclosedByDataEnvironmentExpr = false;
10632  const Expr *EnclosingExpr = nullptr;
10633 
10634  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
10635  VD, CurrentRegionOnly,
10637  StackComponents) -> bool {
10638 
10639  assert(!StackComponents.empty() &&
10640  "Map clause expression with no components!");
10641  assert(StackComponents.back().getAssociatedDeclaration() == VD &&
10642  "Map clause expression with unexpected base!");
10643 
10644  // The whole expression in the stack.
10645  auto *RE = StackComponents.front().getAssociatedExpression();
10646 
10647  // Expressions must start from the same base. Here we detect at which
10648  // point both expressions diverge from each other and see if we can
10649  // detect if the memory referred to both expressions is contiguous and
10650  // do not overlap.
10651  auto CI = CurComponents.rbegin();
10652  auto CE = CurComponents.rend();
10653  auto SI = StackComponents.rbegin();
10654  auto SE = StackComponents.rend();
10655  for (; CI != CE && SI != SE; ++CI, ++SI) {
10656 
10657  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
10658  // At most one list item can be an array item derived from a given
10659  // variable in map clauses of the same construct.
10660  if (CurrentRegionOnly &&
10661  (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
10662  isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
10663  (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
10664  isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
10665  SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
10666  diag::err_omp_multiple_array_items_in_map_clause)
10667  << CI->getAssociatedExpression()->getSourceRange();
10668  SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
10669  diag::note_used_here)
10670  << SI->getAssociatedExpression()->getSourceRange();
10671  return true;
10672  }
10673 
10674  // Do both expressions have the same kind?
10675  if (CI->getAssociatedExpression()->getStmtClass() !=
10676  SI->getAssociatedExpression()->getStmtClass())
10677  break;
10678 
10679  // Are we dealing with different variables/fields?
10680  if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
10681  break;
10682  }
10683 
10684  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
10685  // List items of map clauses in the same construct must not share
10686  // original storage.
10687  //
10688  // If the expressions are exactly the same or one is a subset of the
10689  // other, it means they are sharing storage.
10690  if (CI == CE && SI == SE) {
10691  if (CurrentRegionOnly) {
10692  if (CKind == OMPC_map)
10693  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
10694  else {
10695  assert(CKind == OMPC_to || CKind == OMPC_from);
10696  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
10697  << ERange;
10698  }
10699  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
10700  << RE->getSourceRange();
10701  return true;
10702  } else {
10703  // If we find the same expression in the enclosing data environment,
10704  // that is legal.
10705  IsEnclosedByDataEnvironmentExpr = true;
10706  return false;
10707  }
10708  }
10709 
10710  QualType DerivedType =
10711  std::prev(CI)->getAssociatedDeclaration()->getType();
10712  SourceLocation DerivedLoc =
10713  std::prev(CI)->getAssociatedExpression()->getExprLoc();
10714 
10715  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
10716  // If the type of a list item is a reference to a type T then the type
10717  // will be considered to be T for all purposes of this clause.
10718  DerivedType = DerivedType.getNonReferenceType();
10719 
10720  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
10721  // A variable for which the type is pointer and an array section
10722  // derived from that variable must not appear as list items of map
10723  // clauses of the same construct.
10724  //
10725  // Also, cover one of the cases in:
10726  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
10727  // If any part of the original storage of a list item has corresponding
10728  // storage in the device data environment, all of the original storage
10729  // must have corresponding storage in the device data environment.
10730  //
10731  if (DerivedType->isAnyPointerType()) {
10732  if (CI == CE || SI == SE) {
10733  SemaRef.Diag(
10734  DerivedLoc,
10735  diag::err_omp_pointer_mapped_along_with_derived_section)
10736  << DerivedLoc;
10737  } else {
10738  assert(CI != CE && SI != SE);
10739  SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced)
10740  << DerivedLoc;
10741  }
10742  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
10743  << RE->getSourceRange();
10744  return true;
10745  }
10746 
10747  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
10748  // List items of map clauses in the same construct must not share
10749  // original storage.
10750  //
10751  // An expression is a subset of the other.
10752  if (CurrentRegionOnly && (CI == CE || SI == SE)) {
10753  if (CKind == OMPC_map)
10754  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
10755  else {
10756  assert(CKind == OMPC_to || CKind == OMPC_from);
10757  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
10758  << ERange;
10759  }
10760  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
10761  << RE->getSourceRange();
10762  return true;
10763  }
10764 
10765  // The current expression uses the same base as other expression in the
10766  // data environment but does not contain it completely.
10767  if (!CurrentRegionOnly && SI != SE)
10768  EnclosingExpr = RE;
10769 
10770  // The current expression is a subset of the expression in the data
10771  // environment.
10772  IsEnclosedByDataEnvironmentExpr |=
10773  (!CurrentRegionOnly && CI != CE && SI == SE);
10774 
10775  return false;
10776  });
10777 
10778  if (CurrentRegionOnly)
10779  return FoundError;
10780 
10781  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
10782  // If any part of the original storage of a list item has corresponding
10783  // storage in the device data environment, all of the original storage must
10784  // have corresponding storage in the device data environment.
10785  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
10786  // If a list item is an element of a structure, and a different element of
10787  // the structure has a corresponding list item in the device data environment
10788  // prior to a task encountering the construct associated with the map clause,
10789  // then the list item must also have a corresponding list item in the device
10790  // data environment prior to the task encountering the construct.
10791  //
10792  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
10793  SemaRef.Diag(ELoc,
10794  diag::err_omp_original_storage_is_shared_and_does_not_contain)
10795  << ERange;
10796  SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
10797  << EnclosingExpr->getSourceRange();
10798  return true;
10799  }
10800 
10801  return FoundError;
10802 }
10803 
10804 namespace {
10805 // Utility struct that gathers all the related lists associated with a mappable
10806 // expression.
10807 struct MappableVarListInfo final {
10808  // The list of expressions.
10809  ArrayRef<Expr *> VarList;
10810  // The list of processed expressions.
10811  SmallVector<Expr *, 16> ProcessedVarList;
10812  // The mappble components for each expression.
10814  // The base declaration of the variable.
10815  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
10816 
10817  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
10818  // We have a list of components and base declarations for each entry in the
10819  // variable list.
10820  VarComponents.reserve(VarList.size());
10821  VarBaseDeclarations.reserve(VarList.size());
10822  }
10823 };
10824 }
10825 
10826 // Check the validity of the provided variable list for the provided clause kind
10827 // \a CKind. In the check process the valid expressions, and mappable expression
10828 // components and variables are extracted and used to fill \a Vars,
10829 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
10830 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
10831 static void
10832 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
10833  OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
10834  SourceLocation StartLoc,
10836  bool IsMapTypeImplicit = false) {
10837  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
10838  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
10839  "Unexpected clause kind with mappable expressions!");
10840 
10841  // Keep track of the mappable components and base declarations in this clause.
10842  // Each entry in the list is going to have a list of components associated. We
10843  // record each set of the components so that we can build the clause later on.
10844  // In the end we should have the same amount of declarations and component
10845  // lists.
10846 
10847  for (auto &RE : MVLI.VarList) {
10848  assert(RE && "Null expr in omp to/from/map clause");
10849  SourceLocation ELoc = RE->getExprLoc();
10850 
10851  auto *VE = RE->IgnoreParenLValueCasts();
10852 
10853  if (VE->isValueDependent() || VE->isTypeDependent() ||
10854  VE->isInstantiationDependent() ||
10855  VE->containsUnexpandedParameterPack()) {
10856  // We can only analyze this information once the missing information is
10857  // resolved.
10858  MVLI.ProcessedVarList.push_back(RE);
10859  continue;
10860  }
10861 
10862  auto *SimpleExpr = RE->IgnoreParenCasts();
10863 
10864  if (!RE->IgnoreParenImpCasts()->isLValue()) {
10865  SemaRef.Diag(ELoc,
10866  diag::err_omp_expected_named_var_member_or_array_expression)
10867  << RE->getSourceRange();
10868  continue;
10869  }
10870 
10872  ValueDecl *CurDeclaration = nullptr;
10873 
10874  // Obtain the array or member expression bases if required. Also, fill the
10875  // components array with all the components identified in the process.
10876  auto *BE =
10877  CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind);
10878  if (!BE)
10879  continue;
10880 
10881  assert(!CurComponents.empty() &&
10882  "Invalid mappable expression information.");
10883 
10884  // For the following checks, we rely on the base declaration which is
10885  // expected to be associated with the last component. The declaration is
10886  // expected to be a variable or a field (if 'this' is being mapped).
10887  CurDeclaration = CurComponents.back().getAssociatedDeclaration();
10888  assert(CurDeclaration && "Null decl on map clause.");
10889  assert(
10890  CurDeclaration->isCanonicalDecl() &&
10891  "Expecting components to have associated only canonical declarations.");
10892 
10893  auto *VD = dyn_cast<VarDecl>(CurDeclaration);
10894  auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
10895 
10896  assert((VD || FD) && "Only variables or fields are expected here!");
10897  (void)FD;
10898 
10899  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
10900  // threadprivate variables cannot appear in a map clause.
10901  // OpenMP 4.5 [2.10.5, target update Construct]
10902  // threadprivate variables cannot appear in a from clause.
10903  if (VD && DSAS->isThreadPrivate(VD)) {
10904  auto DVar = DSAS->getTopDSA(VD, false);
10905  SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
10906  << getOpenMPClauseName(CKind);
10907  ReportOriginalDSA(SemaRef, DSAS, VD, DVar);
10908  continue;
10909  }
10910 
10911  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
10912  // A list item cannot appear in both a map clause and a data-sharing
10913  // attribute clause on the same construct.
10914 
10915  // Check conflicts with other map clause expressions. We check the conflicts
10916  // with the current construct separately from the enclosing data
10917  // environment, because the restrictions are different. We only have to
10918  // check conflicts across regions for the map clauses.
10919  if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
10920  /*CurrentRegionOnly=*/true, CurComponents, CKind))
10921  break;
10922  if (CKind == OMPC_map &&
10923  CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
10924  /*CurrentRegionOnly=*/false, CurComponents, CKind))
10925  break;
10926 
10927  // OpenMP 4.5 [2.10.5, target update Construct]
10928  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
10929  // If the type of a list item is a reference to a type T then the type will
10930  // be considered to be T for all purposes of this clause.
10931  QualType Type = CurDeclaration->getType().getNonReferenceType();
10932 
10933  // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
10934  // A list item in a to or from clause must have a mappable type.
10935  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
10936  // A list item must have a mappable type.
10937  if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
10938  DSAS, Type))
10939  continue;
10940 
10941  if (CKind == OMPC_map) {
10942  // target enter data
10943  // OpenMP [2.10.2, Restrictions, p. 99]
10944  // A map-type must be specified in all map clauses and must be either
10945  // to or alloc.
10946  OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
10947  if (DKind == OMPD_target_enter_data &&
10948  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
10949  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
10950  << (IsMapTypeImplicit ? 1 : 0)
10951  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
10952  << getOpenMPDirectiveName(DKind);
10953  continue;
10954  }
10955 
10956  // target exit_data
10957  // OpenMP [2.10.3, Restrictions, p. 102]
10958  // A map-type must be specified in all map clauses and must be either
10959  // from, release, or delete.
10960  if (DKind == OMPD_target_exit_data &&
10961  !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
10962  MapType == OMPC_MAP_delete)) {
10963  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
10964  << (IsMapTypeImplicit ? 1 : 0)
10965  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
10966  << getOpenMPDirectiveName(DKind);
10967  continue;
10968  }
10969 
10970  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
10971  // A list item cannot appear in both a map clause and a data-sharing
10972  // attribute clause on the same construct
10973  if (DKind == OMPD_target && VD) {
10974  auto DVar = DSAS->getTopDSA(VD, false);
10975  if (isOpenMPPrivate(DVar.CKind)) {
10976  SemaRef.Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
10977  << getOpenMPClauseName(DVar.CKind)
10978  << getOpenMPDirectiveName(DSAS->getCurrentDirective());
10979  ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar);
10980  continue;
10981  }
10982  }
10983  }
10984 
10985  // Save the current expression.
10986  MVLI.ProcessedVarList.push_back(RE);
10987 
10988  // Store the components in the stack so that they can be used to check
10989  // against other clauses later on.
10990  DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents);
10991 
10992  // Save the components and declaration to create the clause. For purposes of
10993  // the clause creation, any component list that has has base 'this' uses
10994  // null as base declaration.
10995  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
10996  MVLI.VarComponents.back().append(CurComponents.begin(),
10997  CurComponents.end());
10998  MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
10999  : CurDeclaration);
11000  }
11001 }
11002 
11003 OMPClause *
11005  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
11007  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
11008  SourceLocation LParenLoc, SourceLocation EndLoc) {
11009  MappableVarListInfo MVLI(VarList);
11010  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
11011  MapType, IsMapTypeImplicit);
11012 
11013  // We need to produce a map clause even if we don't have variables so that
11014  // other diagnostics related with non-existing map clauses are accurate.
11015  return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11016  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
11017  MVLI.VarComponents, MapTypeModifier, MapType,
11018  IsMapTypeImplicit, MapLoc);
11019 }
11020 
11023  assert(ParsedType.isUsable());
11024 
11025  QualType ReductionType = GetTypeFromParser(ParsedType.get());
11026  if (ReductionType.isNull())
11027  return QualType();
11028 
11029  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
11030  // A type name in a declare reduction directive cannot be a function type, an
11031  // array type, a reference type, or a type qualified with const, volatile or
11032  // restrict.
11033  if (ReductionType.hasQualifiers()) {
11034  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
11035  return QualType();
11036  }
11037 
11038  if (ReductionType->isFunctionType()) {
11039  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
11040  return QualType();
11041  }
11042  if (ReductionType->isReferenceType()) {
11043  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
11044  return QualType();
11045  }
11046  if (ReductionType->isArrayType()) {
11047  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
11048  return QualType();
11049  }
11050  return ReductionType;
11051 }
11052 
11054  Scope *S, DeclContext *DC, DeclarationName Name,
11055  ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
11056  AccessSpecifier AS, Decl *PrevDeclInScope) {
11057  SmallVector<Decl *, 8> Decls;
11058  Decls.reserve(ReductionTypes.size());
11059 
11060  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
11062  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
11063  // A reduction-identifier may not be re-declared in the current scope for the
11064  // same type or for a type that is compatible according to the base language
11065  // rules.
11066  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
11067  OMPDeclareReductionDecl *PrevDRD = nullptr;
11068  bool InCompoundScope = true;
11069  if (S != nullptr) {
11070  // Find previous declaration with the same name not referenced in other
11071  // declarations.
11073  InCompoundScope =
11074  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
11075  LookupName(Lookup, S);
11076  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
11077  /*AllowInlineNamespace=*/false);
11078  llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
11079  auto Filter = Lookup.makeFilter();
11080  while (Filter.hasNext()) {
11081  auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
11082  if (InCompoundScope) {
11083  auto I = UsedAsPrevious.find(PrevDecl);
11084  if (I == UsedAsPrevious.end())
11085  UsedAsPrevious[PrevDecl] = false;
11086  if (auto *D = PrevDecl->getPrevDeclInScope())
11087  UsedAsPrevious[D] = true;
11088  }
11089  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
11090  PrevDecl->getLocation();
11091  }
11092  Filter.done();
11093  if (InCompoundScope) {
11094  for (auto &PrevData : UsedAsPrevious) {
11095  if (!PrevData.second) {
11096  PrevDRD = PrevData.first;
11097  break;
11098  }
11099  }
11100  }
11101  } else if (PrevDeclInScope != nullptr) {
11102  auto *PrevDRDInScope = PrevDRD =
11103  cast<OMPDeclareReductionDecl>(PrevDeclInScope);
11104  do {
11105  PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
11106  PrevDRDInScope->getLocation();
11107  PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
11108  } while (PrevDRDInScope != nullptr);
11109  }
11110  for (auto &TyData : ReductionTypes) {
11111  auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
11112  bool Invalid = false;
11113  if (I != PreviousRedeclTypes.end()) {
11114  Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
11115  << TyData.first;
11116  Diag(I->second, diag::note_previous_definition);
11117  Invalid = true;
11118  }
11119  PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
11120  auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
11121  Name, TyData.first, PrevDRD);
11122  DC->addDecl(DRD);
11123  DRD->setAccess(AS);
11124  Decls.push_back(DRD);
11125  if (Invalid)
11126  DRD->setInvalidDecl();
11127  else
11128  PrevDRD = DRD;
11129  }
11130 
11131  return DeclGroupPtrTy::make(
11132  DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
11133 }
11134 
11136  auto *DRD = cast<OMPDeclareReductionDecl>(D);
11137 
11138  // Enter new function scope.
11142 
11143  if (S != nullptr)
11144  PushDeclContext(S, DRD);
11145  else
11146  CurContext = DRD;
11147 
11149 
11150  QualType ReductionType = DRD->getType();
11151  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
11152  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
11153  // uses semantics of argument handles by value, but it should be passed by
11154  // reference. C lang does not support references, so pass all parameters as
11155  // pointers.
11156  // Create 'T omp_in;' variable.
11157  auto *OmpInParm =
11158  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
11159  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
11160  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
11161  // uses semantics of argument handles by value, but it should be passed by
11162  // reference. C lang does not support references, so pass all parameters as
11163  // pointers.
11164  // Create 'T omp_out;' variable.
11165  auto *OmpOutParm =
11166  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
11167  if (S != nullptr) {
11168  PushOnScopeChains(OmpInParm, S);
11169  PushOnScopeChains(OmpOutParm, S);
11170  } else {
11171  DRD->addDecl(OmpInParm);
11172  DRD->addDecl(OmpOutParm);
11173  }
11174 }
11175 
11177  auto *DRD = cast<OMPDeclareReductionDecl>(D);
11180 
11181  PopDeclContext();
11183 
11184  if (Combiner != nullptr)
11185  DRD->setCombiner(Combiner);
11186  else
11187  DRD->setInvalidDecl();
11188 }
11189 
11191  auto *DRD = cast<OMPDeclareReductionDecl>(D);
11192 
11193  // Enter new function scope.
11196 
11197  if (S != nullptr)
11198  PushDeclContext(S, DRD);
11199  else
11200  CurContext = DRD;
11201 
11203 
11204  QualType ReductionType = DRD->getType();
11205  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
11206  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
11207  // uses semantics of argument handles by value, but it should be passed by
11208  // reference. C lang does not support references, so pass all parameters as
11209  // pointers.
11210  // Create 'T omp_priv;' variable.
11211  auto *OmpPrivParm =
11212  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
11213  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
11214  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
11215  // uses semantics of argument handles by value, but it should be passed by
11216  // reference. C lang does not support references, so pass all parameters as
11217  // pointers.
11218  // Create 'T omp_orig;' variable.
11219  auto *OmpOrigParm =
11220  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
11221  if (S != nullptr) {
11222  PushOnScopeChains(OmpPrivParm, S);
11223  PushOnScopeChains(OmpOrigParm, S);
11224  } else {
11225  DRD->addDecl(OmpPrivParm);
11226  DRD->addDecl(OmpOrigParm);
11227  }
11228 }
11229 
11231  Expr *Initializer) {
11232  auto *DRD = cast<OMPDeclareReductionDecl>(D);
11235 
11236  PopDeclContext();
11238 
11239  if (Initializer != nullptr)
11240  DRD->setInitializer(Initializer);
11241  else
11242  DRD->setInvalidDecl();
11243 }
11244 
11246  Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
11247  for (auto *D : DeclReductions.get()) {
11248  if (IsValid) {
11249  auto *DRD = cast<OMPDeclareReductionDecl>(D);
11250  if (S != nullptr)
11251  PushOnScopeChains(DRD, S, /*AddToContext=*/false);
11252  } else
11253  D->setInvalidDecl();
11254  }
11255  return DeclReductions;
11256 }
11257 
11259  SourceLocation StartLoc,
11260  SourceLocation LParenLoc,
11261  SourceLocation EndLoc) {
11262  Expr *ValExpr = NumTeams;
11263 
11264  // OpenMP [teams Constrcut, Restrictions]
11265  // The num_teams expression must evaluate to a positive integer value.
11266  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
11267  /*StrictlyPositive=*/true))
11268  return nullptr;
11269 
11270  return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
11271 }
11272 
11274  SourceLocation StartLoc,
11275  SourceLocation LParenLoc,
11276  SourceLocation EndLoc) {
11277  Expr *ValExpr = ThreadLimit;
11278 
11279  // OpenMP [teams Constrcut, Restrictions]
11280  // The thread_limit expression must evaluate to a positive integer value.
11281  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
11282  /*StrictlyPositive=*/true))
11283  return nullptr;
11284 
11285  return new (Context) OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc,
11286  EndLoc);
11287 }
11288 
11290  SourceLocation StartLoc,
11291  SourceLocation LParenLoc,
11292  SourceLocation EndLoc) {
11293  Expr *ValExpr = Priority;
11294 
11295  // OpenMP [2.9.1, task Constrcut]
11296  // The priority-value is a non-negative numerical scalar expression.
11297  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
11298  /*StrictlyPositive=*/false))
11299  return nullptr;
11300 
11301  return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
11302 }
11303 
11305  SourceLocation StartLoc,
11306  SourceLocation LParenLoc,
11307  SourceLocation EndLoc) {
11308  Expr *ValExpr = Grainsize;
11309 
11310  // OpenMP [2.9.2, taskloop Constrcut]
11311  // The parameter of the grainsize clause must be a positive integer
11312  // expression.
11313  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
11314  /*StrictlyPositive=*/true))
11315  return nullptr;
11316 
11317  return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
11318 }
11319 
11321  SourceLocation StartLoc,
11322  SourceLocation LParenLoc,
11323  SourceLocation EndLoc) {
11324  Expr *ValExpr = NumTasks;
11325 
11326  // OpenMP [2.9.2, taskloop Constrcut]
11327  // The parameter of the num_tasks clause must be a positive integer
11328  // expression.
11329  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
11330  /*StrictlyPositive=*/true))
11331  return nullptr;
11332 
11333  return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
11334 }
11335 
11337  SourceLocation LParenLoc,
11338  SourceLocation EndLoc) {
11339  // OpenMP [2.13.2, critical construct, Description]
11340  // ... where hint-expression is an integer constant expression that evaluates
11341  // to a valid lock hint.
11342  ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
11343  if (HintExpr.isInvalid())
11344  return nullptr;
11345  return new (Context)
11346  OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
11347 }
11348 
11350  OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
11351  SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
11352  SourceLocation EndLoc) {
11353  if (Kind == OMPC_DIST_SCHEDULE_unknown) {
11354  std::string Values;
11355  Values += "'";
11356  Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
11357  Values += "'";
11358  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
11359  << Values << getOpenMPClauseName(OMPC_dist_schedule);
11360  return nullptr;
11361  }
11362  Expr *ValExpr = ChunkSize;
11363  Stmt *HelperValStmt = nullptr;
11364  if (ChunkSize) {
11365  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
11366  !ChunkSize->isInstantiationDependent() &&
11367  !ChunkSize->containsUnexpandedParameterPack()) {
11368  SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
11369  ExprResult Val =
11370  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
11371  if (Val.isInvalid())
11372  return nullptr;
11373 
11374  ValExpr = Val.get();
11375 
11376  // OpenMP [2.7.1, Restrictions]
11377  // chunk_size must be a loop invariant integer expression with a positive
11378  // value.
11379  llvm::APSInt Result;
11380  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
11381  if (Result.isSigned() && !Result.isStrictlyPositive()) {
11382  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
11383  << "dist_schedule" << ChunkSize->getSourceRange();
11384  return nullptr;
11385  }
11386  } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) &&
11388  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11389  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11390  HelperValStmt = buildPreInits(Context, Captures);
11391  }
11392  }
11393  }
11394 
11395  return new (Context)
11396  OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
11397  Kind, ValExpr, HelperValStmt);
11398 }
11399 
11402  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
11403  SourceLocation KindLoc, SourceLocation EndLoc) {
11404  // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
11405  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
11406  Kind != OMPC_DEFAULTMAP_scalar) {
11407  std::string Value;
11408  SourceLocation Loc;
11409  Value += "'";
11410  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
11411  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
11412  OMPC_DEFAULTMAP_MODIFIER_tofrom);
11413  Loc = MLoc;
11414  } else {
11415  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
11416  OMPC_DEFAULTMAP_scalar);
11417  Loc = KindLoc;
11418  }
11419  Value += "'";
11420  Diag(Loc, diag::err_omp_unexpected_clause_value)
11421  << Value << getOpenMPClauseName(OMPC_defaultmap);
11422  return nullptr;
11423  }
11424 
11425  return new (Context)
11426  OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
11427 }
11428 
11430  DeclContext *CurLexicalContext = getCurLexicalContext();
11431  if (!CurLexicalContext->isFileContext() &&
11432  !CurLexicalContext->isExternCContext() &&
11433  !CurLexicalContext->isExternCXXContext()) {
11434  Diag(Loc, diag::err_omp_region_not_file_context);
11435  return false;
11436  }
11437  if (IsInOpenMPDeclareTargetContext) {
11438  Diag(Loc, diag::err_omp_enclosed_declare_target);
11439  return false;
11440  }
11441 
11442  IsInOpenMPDeclareTargetContext = true;
11443  return true;
11444 }
11445 
11447  assert(IsInOpenMPDeclareTargetContext &&
11448  "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
11449 
11450  IsInOpenMPDeclareTargetContext = false;
11451 }
11452 
11453 void
11455  const DeclarationNameInfo &Id,
11456  OMPDeclareTargetDeclAttr::MapTypeTy MT,
11457  NamedDeclSetType &SameDirectiveDecls) {
11458  LookupResult Lookup(*this, Id, LookupOrdinaryName);
11459  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
11460 
11461  if (Lookup.isAmbiguous())
11462  return;
11463  Lookup.suppressDiagnostics();
11464 
11465  if (!Lookup.isSingleResult()) {
11466  if (TypoCorrection Corrected =
11467  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
11468  llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
11469  CTK_ErrorRecovery)) {
11470  diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
11471  << Id.getName());
11472  checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
11473  return;
11474  }
11475 
11476  Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
11477  return;
11478  }
11479 
11480  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
11481  if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
11482  if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
11483  Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
11484 
11485  if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) {
11486  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
11487  ND->addAttr(A);
11489  ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
11490  checkDeclIsAllowedInOpenMPTarget(nullptr, ND);
11491  } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
11492  Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
11493  << Id.getName();
11494  }
11495  } else
11496  Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
11497 }
11498 
11500  Sema &SemaRef, Decl *D) {
11501  if (!D)
11502  return;
11503  Decl *LD = nullptr;
11504  if (isa<TagDecl>(D)) {
11505  LD = cast<TagDecl>(D)->getDefinition();
11506  } else if (isa<VarDecl>(D)) {
11507  LD = cast<VarDecl>(D)->getDefinition();
11508 
11509  // If this is an implicit variable that is legal and we do not need to do
11510  // anything.
11511  if (cast<VarDecl>(D)->isImplicit()) {
11512  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11513  SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
11514  D->addAttr(A);
11516  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11517  return;
11518  }
11519 
11520  } else if (isa<FunctionDecl>(D)) {
11521  const FunctionDecl *FD = nullptr;
11522  if (cast<FunctionDecl>(D)->hasBody(FD))
11523  LD = const_cast<FunctionDecl *>(FD);
11524 
11525  // If the definition is associated with the current declaration in the
11526  // target region (it can be e.g. a lambda) that is legal and we do not need
11527  // to do anything else.
11528  if (LD == D) {
11529  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11530  SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
11531  D->addAttr(A);
11533  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11534  return;
11535  }
11536  }
11537  if (!LD)
11538  LD = D;
11539  if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() &&
11540  (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) {
11541  // Outlined declaration is not declared target.
11542  if (LD->isOutOfLine()) {
11543  SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
11544  SemaRef.Diag(SL, diag::note_used_here) << SR;
11545  } else {
11546  DeclContext *DC = LD->getDeclContext();
11547  while (DC) {
11548  if (isa<FunctionDecl>(DC) &&
11549  cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())
11550  break;
11551  DC = DC->getParent();
11552  }
11553  if (DC)
11554  return;
11555 
11556  // Is not declared in target context.
11557  SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
11558  SemaRef.Diag(SL, diag::note_used_here) << SR;
11559  }
11560  // Mark decl as declared target to prevent further diagnostic.
11561  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11562  SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
11563  D->addAttr(A);
11565  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11566  }
11567 }
11568 
11570  Sema &SemaRef, DSAStackTy *Stack,
11571  ValueDecl *VD) {
11572  if (VD->hasAttr<OMPDeclareTargetDeclAttr>())
11573  return true;
11574  if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType()))
11575  return false;
11576  return true;
11577 }
11578 
11580  if (!D || D->isInvalidDecl())
11581  return;
11582  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
11583  SourceLocation SL = E ? E->getLocStart() : D->getLocation();
11584  // 2.10.6: threadprivate variable cannot appear in a declare target directive.
11585  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
11586  if (DSAStack->isThreadPrivate(VD)) {
11587  Diag(SL, diag::err_omp_threadprivate_in_target);
11588  ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
11589  return;
11590  }
11591  }
11592  if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
11593  // Problem if any with var declared with incomplete type will be reported
11594  // as normal, so no need to check it here.
11595  if ((E || !VD->getType()->isIncompleteType()) &&
11596  !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) {
11597  // Mark decl as declared target to prevent further diagnostic.
11598  if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) {
11599  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11600  Context, OMPDeclareTargetDeclAttr::MT_To);
11601  VD->addAttr(A);
11603  ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
11604  }
11605  return;
11606  }
11607  }
11608  if (!E) {
11609  // Checking declaration inside declare target region.
11610  if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
11611  (isa<VarDecl>(D) || isa<FunctionDecl>(D))) {
11612  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11613  Context, OMPDeclareTargetDeclAttr::MT_To);
11614  D->addAttr(A);
11616  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11617  }
11618  return;
11619  }
11620  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
11621 }
11622 
11624  SourceLocation StartLoc,
11625  SourceLocation LParenLoc,
11626  SourceLocation EndLoc) {
11627  MappableVarListInfo MVLI(VarList);
11628  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
11629  if (MVLI.ProcessedVarList.empty())
11630  return nullptr;
11631 
11632  return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11633  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
11634  MVLI.VarComponents);
11635 }
11636 
11638  SourceLocation StartLoc,
11639  SourceLocation LParenLoc,
11640  SourceLocation EndLoc) {
11641  MappableVarListInfo MVLI(VarList);
11642  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
11643  if (MVLI.ProcessedVarList.empty())
11644  return nullptr;
11645 
11646  return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11647  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
11648  MVLI.VarComponents);
11649 }
11650 
11652  SourceLocation StartLoc,
11653  SourceLocation LParenLoc,
11654  SourceLocation EndLoc) {
11656  for (auto &RefExpr : VarList) {
11657  assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
11658  SourceLocation ELoc;
11659  SourceRange ERange;
11660  Expr *SimpleRefExpr = RefExpr;
11661  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11662  if (Res.second) {
11663  // It will be analyzed later.
11664  Vars.push_back(RefExpr);
11665  }
11666  ValueDecl *D = Res.first;
11667  if (!D)
11668  continue;
11669 
11670  QualType Type = D->getType();
11671  // item should be a pointer or reference to pointer
11672  if (!Type.getNonReferenceType()->isPointerType()) {
11673  Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
11674  << 0 << RefExpr->getSourceRange();
11675  continue;
11676  }
11677  Vars.push_back(RefExpr->IgnoreParens());
11678  }
11679 
11680  if (Vars.empty())
11681  return nullptr;
11682 
11683  return OMPUseDevicePtrClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11684  Vars);
11685 }
11686 
11688  SourceLocation StartLoc,
11689  SourceLocation LParenLoc,
11690  SourceLocation EndLoc) {
11692  for (auto &RefExpr : VarList) {
11693  assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
11694  SourceLocation ELoc;
11695  SourceRange ERange;
11696  Expr *SimpleRefExpr = RefExpr;
11697  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11698  if (Res.second) {
11699  // It will be analyzed later.
11700  Vars.push_back(RefExpr);
11701  }
11702  ValueDecl *D = Res.first;
11703  if (!D)
11704  continue;
11705 
11706  QualType Type = D->getType();
11707  // item should be a pointer or array or reference to pointer or array
11708  if (!Type.getNonReferenceType()->isPointerType() &&
11709  !Type.getNonReferenceType()->isArrayType()) {
11710  Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
11711  << 0 << RefExpr->getSourceRange();
11712  continue;
11713  }
11714  Vars.push_back(RefExpr->IgnoreParens());
11715  }
11716 
11717  if (Vars.empty())
11718  return nullptr;
11719 
11720  return OMPIsDevicePtrClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11721  Vars);
11722 }
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.
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=llvm::None)
Called on well-formed 'reduction' clause.
Expr * NLB
Update of LowerBound for statically sheduled 'omp for' loops.
Definition: StmtOpenMP.h:541
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:2411
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:14195
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Definition: StmtOpenMP.h:559
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
Definition: StmtOpenMP.h:557
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
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, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition: Expr.h:408
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1561
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:831
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
static OMPDistributeSimdDirective * 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.
static OMPToClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
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:237
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement...
CanQualType VoidPtrTy
Definition: ASTContext.h:908
unsigned Length
bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)
Called on the start of target region i.e. '#pragma omp declare target'.
A (possibly-)qualified type.
Definition: Type.h:598
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
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:212
base_class_range bases()
Definition: DeclCXX.h:718
bool isInvalid() const
Definition: Ownership.h:160
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:982
ArrayRef< OMPClause * > clauses()
Definition: StmtOpenMP.h:215
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition: Expr.h:3033
DeclContext * getCurLexicalContext() const
Definition: Sema.h:9576
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
Definition: SemaStmt.cpp:3882
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'use_device_ptr' clause.
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:7007
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
Definition: SemaExpr.cpp:3177
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:187
static OMPDistributeParallelForSimdDirective * 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.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr * > Uniforms, ArrayRef< Expr * > Aligneds, ArrayRef< Expr * > Alignments, ArrayRef< Expr * > Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr * > Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc...
Definition: Sema.h:2705
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
Definition: Decl.h:232
Expr * getSimdlen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:481
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
Definition: OpenMPKinds.h:107
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1780
const LangOptions & getLangOpts() const
Definition: Sema.h:1062
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false)
Perform unqualified name lookup starting from a given scope.
static UnresolvedLookupExpr * Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
Definition: ExprCXX.h:2719
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
DeclClass * getAsSingle() const
Definition: Sema/Lookup.h:491
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...
static OMPClauseWithPreInit * get(OMPClause *C)
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Sema/Lookup.h:508
Filter makeFilter()
Create a filter for this result set.
Definition: Sema/Lookup.h:665
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:973
SourceLocation getEndLoc() const
getEndLoc - Retrieve the location of the last token.
static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy)
FullExprArg MakeFullExpr(Expr *Arg)
Definition: Sema.h:3328
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:218
ActionResult< Expr * > ExprResult
Definition: Ownership.h:253
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:819
Expr * EUB
EnsureUpperBound – expression LB = min(LB, NumIterations).
Definition: StmtOpenMP.h:539
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition: Sema.h:1139
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:254
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:197
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
bool isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level)
Check if the specified variable is captured by 'target' directive.
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
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...
StringRef P
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:5542
bool hasDefinition() const
Definition: DeclCXX.h:685
PtrTy get() const
Definition: Ownership.h:164
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
This represents 'priority' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload 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:657
The base class of the type hierarchy.
Definition: Type.h:1281
bool CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
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:922
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
iterator begin() const
Definition: Sema/Lookup.h:319
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:322
QualType getRecordType(const RecordDecl *Decl) const
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
Definition: DeclOpenMP.cpp:62
const Expr * getInit() const
Definition: Decl.h:1139
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:93
A container of type source information.
Definition: Decl.h:62
This represents 'update' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
Definition: Ownership.h:46
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
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:2937
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.
void PopDeclContext()
Definition: SemaDecl.cpp:1120
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target update'.
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2187
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
Definition: OpenMPKinds.h:115
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
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.
const llvm::APInt & getSize() const
Definition: Type.h:2527
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:546
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:81
void setNothrow(bool Nothrow=true)
Definition: Decl.cpp:4078
This represents 'read' clause in the '#pragma omp atomic' directive.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:768
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:25
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:932
DiagnosticsEngine & Diags
Definition: Sema.h:301
This represents 'num_threads' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:334
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
varlist_range varlists()
Definition: OpenMPClause.h:164
Extra information about a function prototype.
Definition: Type.h:3167
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:1813
static OMPTargetParallelForSimdDirective * 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.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:998
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:347
Not a TLS variable.
Definition: Decl.h:785
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
static OMPDistributeParallelForDirective * 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.
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1553
Expr * getNumForLoops() const
Return the number of associated for-loops.
Definition: OpenMPClause.h:913
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition: DeclCXX.h:1169
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
Definition: ScopeInfo.h:627
This represents 'nogroup' clause in the '#pragma omp ...' directive.
void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto)
Definition: SemaDecl.cpp:9988
QualType withConst() const
Retrieves a version of this type with const applied.
This represents 'safelen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:392
Expr * LastIteration
Loop last iteration number.
Definition: StmtOpenMP.h:517
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
Definition: Expr.h:2777
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.
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T)
Definition: DeclOpenMP.cpp:92
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
Definition: OpenMPKinds.cpp:62
DeclarationName getName() const
getName - Returns the embedded declaration name.
One of these records is kept for each identifier that is lexed.
iterator end() const
Definition: Sema/Lookup.h:320
bool isScalarType() const
Definition: Type.h:5715
CalcStep
Definition: OpenMPClause.h:313
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
bool isUnset() const
Definition: Ownership.h:162
Step
Definition: OpenMPClause.h:313
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4549
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition: Type.h:1789
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
A C++ nested-name-specifier augmented with source location information.
ExprResult ExprEmpty()
Definition: Ownership.h:274
This represents 'simd' clause in the '#pragma omp ...' directive.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
Definition: OpenMPClause.h:826
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 IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isReferenceType() const
Definition: Type.h:5491
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop or taksloop simd...
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Definition: OpenMPKinds.h:84
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Definition: Decl.h:2293
bool isAnyPointerType() const
Definition: Type.h:5485
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
Definition: SemaDecl.cpp:54
SourceLocation getLocStart() const
Returns the starting location of the clause.
Definition: OpenMPClause.h:46
void Deallocate(void *Ptr) const
Definition: ASTContext.h:574
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:2521
bool isTranslationUnit() const
Definition: DeclBase.h:1283
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:1982
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:834
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.
static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< Expr *, DeclRefExpr * > &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
Definition: SemaExpr.cpp:509
void PopExpressionEvaluationContext()
Definition: SemaExpr.cpp:12840
This represents '#pragma omp critical' directive.
Definition: StmtOpenMP.h:1228
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2007
void EndOpenMPClause()
End analysis of clauses.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
IdentifierTable & Idents
Definition: ASTContext.h:459
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:105
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:449
Expr * getLHS() const
Definition: Expr.h:2943
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.
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
Definition: OpenMPKinds.h:100
static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, const ValueDecl *D, DSAStackTy::DSAVarData DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'is_device_ptr' clause.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Definition: OpenMPClause.h:842
static OMPTargetParallelForDirective * 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:738
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:585
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
bool IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level)
Return true if the provided declaration VD should be captured by reference.
Definition: SemaOpenMP.cpp:842
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:588
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer)
Finish current declare reduction construct initializer.
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement...
void ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
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.
static ValueDecl * getCanonicalDecl(ValueDecl *D)
Definition: SemaOpenMP.cpp:393
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'from' clause.
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
Definition: SemaOpenMP.cpp:634
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:135
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
StmtResult StmtError()
Definition: Ownership.h:269
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:2897
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:147
Look up the name of an OpenMP user-defined reduction operation.
Definition: Sema.h:2743
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:3471
This represents 'default' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:554
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:39
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:6208
OMPClause * ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'map' clause.
This represents 'final' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:280
This represents 'mergeable' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:992
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
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:847
void append(iterator I, iterator E)
Expr * CalcLastIteration
Calculation of last iteration.
Definition: StmtOpenMP.h:521
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:2632
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
Definition: Type.cpp:1892
static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:812
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:980
Preprocessor & PP
Definition: Sema.h:298
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:121
detail::InMemoryDirectory::const_iterator I
static T filterLookupForUDR(SmallVectorImpl< UnresolvedSet< 8 >> &Lookups, const llvm::function_ref< T(ValueDecl *)> &Gen)
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var)
Mark a variable referenced, and check whether it is odr-used (C++ [basic.def.odr]p2, C99 6.9p3).
Definition: SemaExpr.cpp:13984
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
QualType getType() const
Definition: Decl.h:599
bool isInvalid() const
const LangOptions & LangOpts
Definition: Sema.h:297
Expr * NUB
Update of UpperBound for statically sheduled 'omp for' loops.
Definition: StmtOpenMP.h:543
The lookup results will be used for redeclaration of a name, if an entity by that name already exists...
Definition: Sema.h:2756
Expr * Cond
Loop condition.
Definition: StmtOpenMP.h:525
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:523
static const Decl * getDefinition(const Decl *D)
Definition: SemaDecl.cpp:2321
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:513
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:3170
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:263
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, bool TypeMayContainAuto)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Definition: SemaDecl.cpp:9517
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:10772
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate', 'reduction' etc.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
Definition: Expr.cpp:1652
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL)
Definition: DeclOpenMP.cpp:29
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:189
Expr * IterationVarRef
Loop iteration variable.
Definition: StmtOpenMP.h:515
const SmallVectorImpl< AnnotatedLine * >::const_iterator End
sema::FunctionScopeInfo * getEnclosingFunction() const
Definition: Sema.h:1192
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
Definition: Type.h:5403
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:415
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:688
static OMPIsDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Allows QualTypes to be sorted and hence used in maps and sets.
const Type * getTypePtrOrNull() const
Definition: Type.h:5263
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:626
This represents 'capture' clause in the '#pragma omp atomic' directive.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Definition: Decl.h:590
Expr - This represents one expression.
Definition: Expr.h:105
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
Allow any unmodeled side effect.
Definition: Expr.h:589
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:102
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
Definition: Scope.h:309
bool isAnyComplexType() const
Definition: Type.h:5545
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:447
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)
OMPDeclareReductionDecl * getPrevDeclInScope()
Get reference to previous declare reduction construct in the same scope with the same name...
Definition: DeclOpenMP.cpp:76
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
Definition: DeclBase.cpp:981
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
Inits[]
Definition: OpenMPClause.h:312
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:302
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Sema/Lookup.h:501
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:12635
OpenMPClauseKind
OpenMP clauses.
Definition: OpenMPKinds.h:33
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, const Decl *D=nullptr, const BlockExpr *blkExpr=nullptr)
Definition: Sema.cpp:1152
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
Definition: Expr.cpp:746
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:6826
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
Definition: StmtOpenMP.h:565
This represents 'ordered' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:878
void DiscardCleanupsInEvaluationContext()
Definition: SemaExpr.cpp:12898
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:549
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:631
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1774
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1214
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)
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement...
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:1066
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:502
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
Definition: SemaDecl.cpp:1244
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr * > PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
ValueDecl * getDecl()
Definition: Expr.h:1017
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:790
bool isGLValue() const
Definition: Expr.h:250
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2461
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:51
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
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:881
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
VarDecl * getCanonicalDecl() override
Definition: Decl.cpp:1908
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
Definition: SemaOpenMP.cpp:42
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
Definition: Expr.h:1423
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:519
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
Definition: Sema.h:4903
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:960
bool isAmbiguous() const
Definition: Sema/Lookup.h:285
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:2593
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:3526
Expr * ST
Stride - local variable passed to runtime.
Definition: StmtOpenMP.h:537
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:553
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D)
Check declaration inside target region.
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:848
static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause * > Clauses)
#define false
Definition: stdbool.h:33
Kind
This captures a statement into a function.
Definition: Stmt.h:2006
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Definition: StmtOpenMP.h:551
static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< Expr *, DeclRefExpr * > *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
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:76
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5259
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
This represents '#pragma omp declare reduction ...' directive.
Definition: DeclOpenMP.h:102
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
bool isConstant(const ASTContext &Ctx) const
Definition: Type.h:735
Pseudo declaration for capturing expressions.
Definition: DeclOpenMP.h:171
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement...
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:855
VarDecl * IsOpenMPCapturedDecl(ValueDecl *D)
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
Definition: SemaOpenMP.cpp:980
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...
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:698
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, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
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:1069
bool getSuppressAllDiagnostics() const
Definition: Diagnostic.h:475
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'to' clause.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:443
OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:23
IdentifierTable & getIdentifierTable()
Definition: Preprocessor.h:697
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:764
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
Definition: Specifiers.h:119
StmtResult ActOnCapturedRegionEnd(Stmt *S)
Definition: SemaStmt.cpp:3977
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:178
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
Definition: OpenMPClause.h:262
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:630
C-style initialization with assignment.
Definition: Decl.h:778
This file defines OpenMP nodes for declarative directives.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Definition: DeclSpec.h:194
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.
static OMPFromClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
CanQualType VoidTy
Definition: ASTContext.h:893
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void addDecl(NamedDecl *D)
Definition: UnresolvedSet.h:82
Describes the kind of initialization being performed, along with location information for tokens rela...
This declaration is only a declaration.
Definition: Decl.h:1069
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
SourceLocation getBegin() const
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:165
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:5849
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:125
Updates[]
Definition: OpenMPClause.h:312
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:1279
PtrTy get() const
Definition: Ownership.h:75
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, bool IsMapTypeImplicit=false)
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1188
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
Definition: Sema.cpp:1511
Expr * LB
LowerBound - local variable passed to runtime.
Definition: StmtOpenMP.h:533
void clear(unsigned Size)
Initialize all the fields to null.
Definition: StmtOpenMP.h:573
Expr * Init
Loop iteration variable init.
Definition: StmtOpenMP.h:527
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
#define DSAStack
Definition: SemaOpenMP.cpp:840
SourceLocation getLocStart() const LLVM_READONLY
Definition: Expr.cpp:427
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:977
bool isDynamicClass() const
Definition: DeclCXX.h:698
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
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)
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:475
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:398
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
QualType getType() const
Definition: Expr.h:126
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< Expr *, DeclRefExpr * > &Captures)
Build 'VarRef = Start.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
Definition: DeclGroup.h:71
* Finals[]
Definition: OpenMPClause.h:313
static Stmt * buildPreInits(ASTContext &Context, SmallVectorImpl< Decl * > &PreInits)
Build preinits statement for the given declarations.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
Definition: OpenMPKinds.h:67
This represents 'device' clause in the '#pragma omp ...' directive.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1135
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Definition: StmtOpenMP.h:555
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:22
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:3961
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
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.
DeclarationName - The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
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:247
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
Definition: SemaDecl.cpp:1113
This represents clause 'linear' in the '#pragma omp ...' directives.
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause * > Clauses)
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Definition: StmtOpenMP.h:1286
StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
detail::InMemoryDirectory::const_iterator E
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
static Expr * CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind)
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Sema/Lookup.h:292
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:1966
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...
static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Definition: Expr.cpp:2413
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:5432
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored, perform any conversions that are required.
bool empty() const
Return true if no decls were found.
Definition: Sema/Lookup.h:323
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
Not an overloaded operator.
Definition: OperatorKinds.h:23
Expr * getSafelen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:426
void ActOnFinishOpenMPDeclareTargetDirective()
Called at the end of target region i.e. '#pragme omp end declare target'.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:3707
Complex values, per C99 6.2.5p11.
Definition: Type.h:2119
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:5818
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2063
QualType getCanonicalType() const
Definition: Type.h:5298
This file defines OpenMP AST classes for executable directives and clauses.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, bool IsDecltype=false)
Definition: SemaExpr.cpp:12822
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Definition: Diagnostic.cpp:181
CanQualType DependentTy
Definition: ASTContext.h:909
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:1309
Expr * Inc
Loop increment.
Definition: StmtOpenMP.h:529
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Definition: OpenMPKinds.h:59
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:178
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:103
CXXBasePath & front()
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2319
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1528
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
Definition: SemaExpr.cpp:11302
QualType withRestrict() const
Definition: Type.h:780
OpenMPDefaultClauseKind
OpenMP attributes for 'default' clause.
Definition: OpenMPKinds.h:43
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1296
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:276
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:2936
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1058
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:958
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
Definition: OpenMPKinds.cpp:31
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:2533
bool isUsable() const
Definition: Ownership.h:161
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
QualType getPointeeType() const
Definition: Type.h:2340
bool isTLSSupported() const
Whether the target supports thread-local storage.
static OMPUseDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Expr * getBase() const
Definition: Expr.h:2405
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:12171
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition: Stmt.cpp:1084
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Call-style initialization (C++98)
Definition: Decl.h:779
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Definition: Sema.h:290
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:500
ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:1724
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:2315
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
void setSuppressAllDiagnostics(bool Val=true)
Suppress all diagnostics, to silence the front end when we know that we don't want any more diagnosti...
Definition: Diagnostic.h:472
Expr * UB
UpperBound - local variable passed to runtime.
Definition: StmtOpenMP.h:535
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
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:5339
This represents 'nowait' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:929
void setEnd(SourceLocation e)
void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OMPDeclareTargetDeclAttr::MapTypeTy MT, NamedDeclSetType &SameDirectiveDecls)
Called on correct id-expression from the '#pragma omp declare target'.
Represents a C++ struct/union/class.
Definition: DeclCXX.h:263
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:3887
Opcode getOpcode() const
Definition: Expr.h:2940
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:515
Privates[]
Gets the list of initial values for linear variables.
Definition: OpenMPClause.h:312
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Definition: OpenMPKinds.h:92
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
Definition: DeclBase.cpp:1270
Do not present this diagnostic, ignore it.
static bool HasMapClause(ArrayRef< OMPClause * > Clauses)
Check for existence of a map clause in the list of clauses.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Definition: Type.h:5756
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:311
static OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
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:229
bool isArrayType() const
Definition: Type.h:5521
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2148
Expr * getRHS() const
Definition: Expr.h:2945
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:543
ExprResult ExprError()
Definition: Ownership.h:268
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
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, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc)
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:618
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:529
static OpaquePtr make(PtrTy P)
Definition: Ownership.h:55
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
Stmt * PreInits
Init statement for all captured expressions.
Definition: StmtOpenMP.h:561
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:932
bool isSet() const
Deprecated.
Definition: DeclSpec.h:209
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:1742
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:714
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Sema/Lookup.h:566
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
Definition: ScopeInfo.h:165
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:109
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:531
A trivial tuple used to represent a source range.
ASTContext & Context
Definition: Sema.h:299
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...
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
Definition: SemaExpr.cpp:14371
NamedDecl - This represents a decl with a name.
Definition: Decl.h:213
static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:564
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:609
CanQualType BoolTy
Definition: ASTContext.h:894
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:11224
static OMPClauseWithPostUpdate * get(OMPClause *C)
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:1736
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:665
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
This represents '#pragma omp threadprivate ...' directive.
Definition: DeclOpenMP.h:39
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:2512
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
void clear()
Clears out any current state.
Definition: Sema/Lookup.h:538
void PushFunctionScope()
Enter a new function scope.
Definition: Sema.cpp:1120
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Attr - This represents one attribute.
Definition: Attr.h:45
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:5702
Helper class that creates diagnostics with optional template instantiation stacks.
Definition: Sema.h:1092
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Definition: Expr.cpp:2295
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement...
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement...
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, bool AllowInlineNamespace)
Filters out lookup results that don't fall within the given scope as determined by isDeclInScope...
Definition: SemaDecl.cpp:1331
bool isPointerType() const
Definition: Type.h:5482