clang  3.7.0
SemaOpenMP.cpp
Go to the documentation of this file.
1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// \brief This file implements semantic analysis for OpenMP directives and
11 /// clauses.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "TreeTransform.h"
16 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/StmtCXX.h"
22 #include "clang/AST/StmtOpenMP.h"
23 #include "clang/AST/StmtVisitor.h"
25 #include "clang/Basic/TargetInfo.h"
26 #include "clang/Lex/Preprocessor.h"
28 #include "clang/Sema/Lookup.h"
29 #include "clang/Sema/Scope.h"
30 #include "clang/Sema/ScopeInfo.h"
32 using namespace clang;
33 
34 //===----------------------------------------------------------------------===//
35 // Stack of data-sharing attributes for variables
36 //===----------------------------------------------------------------------===//
37 
38 namespace {
39 /// \brief Default data sharing attributes, which can be applied to directive.
41  DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
42  DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'.
43  DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'.
44 };
45 
46 template <class T> struct MatchesAny {
47  explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {}
48  bool operator()(T Kind) {
49  for (auto KindEl : Arr)
50  if (KindEl == Kind)
51  return true;
52  return false;
53  }
54 
55 private:
56  ArrayRef<T> Arr;
57 };
58 struct MatchesAlways {
59  MatchesAlways() {}
60  template <class T> bool operator()(T) { return true; }
61 };
62 
63 typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause;
64 typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective;
65 
66 /// \brief Stack for tracking declarations used in OpenMP directives and
67 /// clauses and their data-sharing attributes.
68 class DSAStackTy {
69 public:
70  struct DSAVarData {
71  OpenMPDirectiveKind DKind;
72  OpenMPClauseKind CKind;
73  DeclRefExpr *RefExpr;
74  SourceLocation ImplicitDSALoc;
75  DSAVarData()
76  : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr),
77  ImplicitDSALoc() {}
78  };
79 
80 private:
81  struct DSAInfo {
82  OpenMPClauseKind Attributes;
83  DeclRefExpr *RefExpr;
84  };
85  typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
86  typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
87  typedef llvm::DenseSet<VarDecl *> LoopControlVariablesSetTy;
88 
89  struct SharingMapTy {
90  DeclSAMapTy SharingMap;
91  AlignedMapTy AlignedMap;
92  LoopControlVariablesSetTy LCVSet;
93  DefaultDataSharingAttributes DefaultAttr;
94  SourceLocation DefaultAttrLoc;
96  DeclarationNameInfo DirectiveName;
97  Scope *CurScope;
98  SourceLocation ConstructLoc;
99  bool OrderedRegion;
100  bool NowaitRegion;
101  unsigned CollapseNumber;
102  SourceLocation InnerTeamsRegionLoc;
103  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
104  Scope *CurScope, SourceLocation Loc)
105  : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
106  Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
107  ConstructLoc(Loc), OrderedRegion(false), NowaitRegion(false),
108  CollapseNumber(1), InnerTeamsRegionLoc() {}
109  SharingMapTy()
110  : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
111  Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
112  ConstructLoc(), OrderedRegion(false), NowaitRegion(false),
113  CollapseNumber(1), InnerTeamsRegionLoc() {}
114  };
115 
116  typedef SmallVector<SharingMapTy, 64> StackTy;
117 
118  /// \brief Stack of used declaration and their data-sharing attributes.
119  StackTy Stack;
120  /// \brief true, if check for DSA must be from parent directive, false, if
121  /// from current directive.
122  OpenMPClauseKind ClauseKindMode;
123  Sema &SemaRef;
124  bool ForceCapturing;
125 
126  typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
127 
128  DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D);
129 
130  /// \brief Checks if the variable is a local for OpenMP region.
131  bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
132 
133 public:
134  explicit DSAStackTy(Sema &S)
135  : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S),
136  ForceCapturing(false) {}
137 
138  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
139  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
140 
141  bool isForceVarCapturing() const { return ForceCapturing; }
142  void setForceVarCapturing(bool V) { ForceCapturing = V; }
143 
144  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
145  Scope *CurScope, SourceLocation Loc) {
146  Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
147  Stack.back().DefaultAttrLoc = Loc;
148  }
149 
150  void pop() {
151  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!");
152  Stack.pop_back();
153  }
154 
155  /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
156  /// add it and return NULL; otherwise return previous occurrence's expression
157  /// for diagnostics.
158  DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE);
159 
160  /// \brief Register specified variable as loop control variable.
161  void addLoopControlVariable(VarDecl *D);
162  /// \brief Check if the specified variable is a loop control variable for
163  /// current region.
164  bool isLoopControlVariable(VarDecl *D);
165 
166  /// \brief Adds explicit data sharing attribute to the specified declaration.
167  void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
168 
169  /// \brief Returns data sharing attributes from top of the stack for the
170  /// specified declaration.
171  DSAVarData getTopDSA(VarDecl *D, bool FromParent);
172  /// \brief Returns data-sharing attributes for the specified declaration.
173  DSAVarData getImplicitDSA(VarDecl *D, bool FromParent);
174  /// \brief Checks if the specified variables has data-sharing attributes which
175  /// match specified \a CPred predicate in any directive which matches \a DPred
176  /// predicate.
177  template <class ClausesPredicate, class DirectivesPredicate>
178  DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred,
179  DirectivesPredicate DPred, bool FromParent);
180  /// \brief Checks if the specified variables has data-sharing attributes which
181  /// match specified \a CPred predicate in any innermost directive which
182  /// matches \a DPred predicate.
183  template <class ClausesPredicate, class DirectivesPredicate>
184  DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
185  DirectivesPredicate DPred,
186  bool FromParent);
187  /// \brief Checks if the specified variables has explicit data-sharing
188  /// attributes which match specified \a CPred predicate at the specified
189  /// OpenMP region.
190  bool hasExplicitDSA(VarDecl *D,
191  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
192  unsigned Level);
193  /// \brief Finds a directive which matches specified \a DPred predicate.
194  template <class NamedDirectivesPredicate>
195  bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent);
196 
197  /// \brief Returns currently analyzed directive.
198  OpenMPDirectiveKind getCurrentDirective() const {
199  return Stack.back().Directive;
200  }
201  /// \brief Returns parent directive.
202  OpenMPDirectiveKind getParentDirective() const {
203  if (Stack.size() > 2)
204  return Stack[Stack.size() - 2].Directive;
205  return OMPD_unknown;
206  }
207 
208  /// \brief Set default data sharing attribute to none.
209  void setDefaultDSANone(SourceLocation Loc) {
210  Stack.back().DefaultAttr = DSA_none;
211  Stack.back().DefaultAttrLoc = Loc;
212  }
213  /// \brief Set default data sharing attribute to shared.
214  void setDefaultDSAShared(SourceLocation Loc) {
215  Stack.back().DefaultAttr = DSA_shared;
216  Stack.back().DefaultAttrLoc = Loc;
217  }
218 
219  DefaultDataSharingAttributes getDefaultDSA() const {
220  return Stack.back().DefaultAttr;
221  }
222  SourceLocation getDefaultDSALocation() const {
223  return Stack.back().DefaultAttrLoc;
224  }
225 
226  /// \brief Checks if the specified variable is a threadprivate.
227  bool isThreadPrivate(VarDecl *D) {
228  DSAVarData DVar = getTopDSA(D, false);
229  return isOpenMPThreadPrivate(DVar.CKind);
230  }
231 
232  /// \brief Marks current region as ordered (it has an 'ordered' clause).
233  void setOrderedRegion(bool IsOrdered = true) {
234  Stack.back().OrderedRegion = IsOrdered;
235  }
236  /// \brief Returns true, if parent region is ordered (has associated
237  /// 'ordered' clause), false - otherwise.
238  bool isParentOrderedRegion() const {
239  if (Stack.size() > 2)
240  return Stack[Stack.size() - 2].OrderedRegion;
241  return false;
242  }
243  /// \brief Marks current region as nowait (it has a 'nowait' clause).
244  void setNowaitRegion(bool IsNowait = true) {
245  Stack.back().NowaitRegion = IsNowait;
246  }
247  /// \brief Returns true, if parent region is nowait (has associated
248  /// 'nowait' clause), false - otherwise.
249  bool isParentNowaitRegion() const {
250  if (Stack.size() > 2)
251  return Stack[Stack.size() - 2].NowaitRegion;
252  return false;
253  }
254 
255  /// \brief Set collapse value for the region.
256  void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; }
257  /// \brief Return collapse value for region.
258  unsigned getCollapseNumber() const {
259  return Stack.back().CollapseNumber;
260  }
261 
262  /// \brief Marks current target region as one with closely nested teams
263  /// region.
264  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
265  if (Stack.size() > 2)
266  Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc;
267  }
268  /// \brief Returns true, if current region has closely nested teams region.
269  bool hasInnerTeamsRegion() const {
270  return getInnerTeamsRegionLoc().isValid();
271  }
272  /// \brief Returns location of the nested teams region (if any).
273  SourceLocation getInnerTeamsRegionLoc() const {
274  if (Stack.size() > 1)
275  return Stack.back().InnerTeamsRegionLoc;
276  return SourceLocation();
277  }
278 
279  Scope *getCurScope() const { return Stack.back().CurScope; }
280  Scope *getCurScope() { return Stack.back().CurScope; }
281  SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
282 };
283 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
284  return isOpenMPParallelDirective(DKind) || DKind == OMPD_task ||
285  isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
286 }
287 } // namespace
288 
289 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
290  VarDecl *D) {
291  D = D->getCanonicalDecl();
292  DSAVarData DVar;
293  if (Iter == std::prev(Stack.rend())) {
294  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
295  // in a region but not in construct]
296  // File-scope or namespace-scope variables referenced in called routines
297  // in the region are shared unless they appear in a threadprivate
298  // directive.
299  if (!D->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
300  DVar.CKind = OMPC_shared;
301 
302  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
303  // in a region but not in construct]
304  // Variables with static storage duration that are declared in called
305  // routines in the region are shared.
306  if (D->hasGlobalStorage())
307  DVar.CKind = OMPC_shared;
308 
309  return DVar;
310  }
311 
312  DVar.DKind = Iter->Directive;
313  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
314  // in a Construct, C/C++, predetermined, p.1]
315  // Variables with automatic storage duration that are declared in a scope
316  // inside the construct are private.
317  if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() &&
318  (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
319  DVar.CKind = OMPC_private;
320  return DVar;
321  }
322 
323  // Explicitly specified attributes and local variables with predetermined
324  // attributes.
325  if (Iter->SharingMap.count(D)) {
326  DVar.RefExpr = Iter->SharingMap[D].RefExpr;
327  DVar.CKind = Iter->SharingMap[D].Attributes;
328  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
329  return DVar;
330  }
331 
332  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
333  // in a Construct, C/C++, implicitly determined, p.1]
334  // In a parallel or task construct, the data-sharing attributes of these
335  // variables are determined by the default clause, if present.
336  switch (Iter->DefaultAttr) {
337  case DSA_shared:
338  DVar.CKind = OMPC_shared;
339  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
340  return DVar;
341  case DSA_none:
342  return DVar;
343  case DSA_unspecified:
344  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
345  // in a Construct, implicitly determined, p.2]
346  // In a parallel construct, if no default clause is present, these
347  // variables are shared.
348  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
349  if (isOpenMPParallelDirective(DVar.DKind) ||
350  isOpenMPTeamsDirective(DVar.DKind)) {
351  DVar.CKind = OMPC_shared;
352  return DVar;
353  }
354 
355  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
356  // in a Construct, implicitly determined, p.4]
357  // In a task construct, if no default clause is present, a variable that in
358  // the enclosing context is determined to be shared by all implicit tasks
359  // bound to the current team is shared.
360  if (DVar.DKind == OMPD_task) {
361  DSAVarData DVarTemp;
362  for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend();
363  I != EE; ++I) {
364  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
365  // Referenced
366  // in a Construct, implicitly determined, p.6]
367  // In a task construct, if no default clause is present, a variable
368  // whose data-sharing attribute is not determined by the rules above is
369  // firstprivate.
370  DVarTemp = getDSA(I, D);
371  if (DVarTemp.CKind != OMPC_shared) {
372  DVar.RefExpr = nullptr;
373  DVar.DKind = OMPD_task;
374  DVar.CKind = OMPC_firstprivate;
375  return DVar;
376  }
377  if (isParallelOrTaskRegion(I->Directive))
378  break;
379  }
380  DVar.DKind = OMPD_task;
381  DVar.CKind =
382  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
383  return DVar;
384  }
385  }
386  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
387  // in a Construct, implicitly determined, p.3]
388  // For constructs other than task, if no default clause is present, these
389  // variables inherit their data-sharing attributes from the enclosing
390  // context.
391  return getDSA(std::next(Iter), D);
392 }
393 
394 DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) {
395  assert(Stack.size() > 1 && "Data sharing attributes stack is empty");
396  D = D->getCanonicalDecl();
397  auto It = Stack.back().AlignedMap.find(D);
398  if (It == Stack.back().AlignedMap.end()) {
399  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
400  Stack.back().AlignedMap[D] = NewDE;
401  return nullptr;
402  } else {
403  assert(It->second && "Unexpected nullptr expr in the aligned map");
404  return It->second;
405  }
406  return nullptr;
407 }
408 
409 void DSAStackTy::addLoopControlVariable(VarDecl *D) {
410  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
411  D = D->getCanonicalDecl();
412  Stack.back().LCVSet.insert(D);
413 }
414 
415 bool DSAStackTy::isLoopControlVariable(VarDecl *D) {
416  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
417  D = D->getCanonicalDecl();
418  return Stack.back().LCVSet.count(D) > 0;
419 }
420 
421 void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
422  D = D->getCanonicalDecl();
423  if (A == OMPC_threadprivate) {
424  Stack[0].SharingMap[D].Attributes = A;
425  Stack[0].SharingMap[D].RefExpr = E;
426  } else {
427  assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
428  Stack.back().SharingMap[D].Attributes = A;
429  Stack.back().SharingMap[D].RefExpr = E;
430  }
431 }
432 
433 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
434  D = D->getCanonicalDecl();
435  if (Stack.size() > 2) {
436  reverse_iterator I = Iter, E = std::prev(Stack.rend());
437  Scope *TopScope = nullptr;
438  while (I != E && !isParallelOrTaskRegion(I->Directive)) {
439  ++I;
440  }
441  if (I == E)
442  return false;
443  TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
444  Scope *CurScope = getCurScope();
445  while (CurScope != TopScope && !CurScope->isDeclScope(D)) {
446  CurScope = CurScope->getParent();
447  }
448  return CurScope != TopScope;
449  }
450  return false;
451 }
452 
453 /// \brief Build a variable declaration for OpenMP loop iteration variable.
455  StringRef Name) {
456  DeclContext *DC = SemaRef.CurContext;
457  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
458  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
459  VarDecl *Decl =
460  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
461  Decl->setImplicit();
462  return Decl;
463 }
464 
466  SourceLocation Loc,
467  bool RefersToCapture = false) {
468  D->setReferenced();
469  D->markUsed(S.Context);
471  SourceLocation(), D, RefersToCapture, Loc, Ty,
472  VK_LValue);
473 }
474 
475 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
476  D = D->getCanonicalDecl();
477  DSAVarData DVar;
478 
479  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
480  // in a Construct, C/C++, predetermined, p.1]
481  // Variables appearing in threadprivate directives are threadprivate.
482  if ((D->getTLSKind() != VarDecl::TLS_None &&
483  !(D->hasAttr<OMPThreadPrivateDeclAttr>() &&
484  SemaRef.getLangOpts().OpenMPUseTLS &&
485  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
486  (D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() &&
487  !D->isLocalVarDecl())) {
488  addDSA(D, buildDeclRefExpr(SemaRef, D, D->getType().getNonReferenceType(),
489  D->getLocation()),
491  }
492  if (Stack[0].SharingMap.count(D)) {
493  DVar.RefExpr = Stack[0].SharingMap[D].RefExpr;
494  DVar.CKind = OMPC_threadprivate;
495  return DVar;
496  }
497 
498  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
499  // in a Construct, C/C++, predetermined, p.1]
500  // Variables with automatic storage duration that are declared in a scope
501  // inside the construct are private.
502  OpenMPDirectiveKind Kind =
503  FromParent ? getParentDirective() : getCurrentDirective();
504  auto StartI = std::next(Stack.rbegin());
505  auto EndI = std::prev(Stack.rend());
506  if (FromParent && StartI != EndI) {
507  StartI = std::next(StartI);
508  }
509  if (!isParallelOrTaskRegion(Kind)) {
510  if (isOpenMPLocal(D, StartI) &&
511  ((D->isLocalVarDecl() && (D->getStorageClass() == SC_Auto ||
512  D->getStorageClass() == SC_None)) ||
513  isa<ParmVarDecl>(D))) {
514  DVar.CKind = OMPC_private;
515  return DVar;
516  }
517 
518  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
519  // in a Construct, C/C++, predetermined, p.4]
520  // Static data members are shared.
521  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
522  // in a Construct, C/C++, predetermined, p.7]
523  // Variables with static storage duration that are declared in a scope
524  // inside the construct are shared.
525  if (D->isStaticDataMember() || D->isStaticLocal()) {
526  DSAVarData DVarTemp =
527  hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent);
528  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
529  return DVar;
530 
531  DVar.CKind = OMPC_shared;
532  return DVar;
533  }
534  }
535 
537  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
538  Type = SemaRef.getASTContext().getBaseElementType(Type);
539  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
540  // in a Construct, C/C++, predetermined, p.6]
541  // Variables with const qualified type having no mutable member are
542  // shared.
543  CXXRecordDecl *RD =
544  SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
545  if (IsConstant &&
546  !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
547  // Variables with const-qualified type having no mutable member may be
548  // listed in a firstprivate clause, even if they are static data members.
549  DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate),
550  MatchesAlways(), FromParent);
551  if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
552  return DVar;
553 
554  DVar.CKind = OMPC_shared;
555  return DVar;
556  }
557 
558  // Explicitly specified attributes and local variables with predetermined
559  // attributes.
560  auto I = std::prev(StartI);
561  if (I->SharingMap.count(D)) {
562  DVar.RefExpr = I->SharingMap[D].RefExpr;
563  DVar.CKind = I->SharingMap[D].Attributes;
564  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
565  }
566 
567  return DVar;
568 }
569 
570 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D, bool FromParent) {
571  D = D->getCanonicalDecl();
572  auto StartI = Stack.rbegin();
573  auto EndI = std::prev(Stack.rend());
574  if (FromParent && StartI != EndI) {
575  StartI = std::next(StartI);
576  }
577  return getDSA(StartI, D);
578 }
579 
580 template <class ClausesPredicate, class DirectivesPredicate>
581 DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred,
582  DirectivesPredicate DPred,
583  bool FromParent) {
584  D = D->getCanonicalDecl();
585  auto StartI = std::next(Stack.rbegin());
586  auto EndI = std::prev(Stack.rend());
587  if (FromParent && StartI != EndI) {
588  StartI = std::next(StartI);
589  }
590  for (auto I = StartI, EE = EndI; I != EE; ++I) {
591  if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
592  continue;
593  DSAVarData DVar = getDSA(I, D);
594  if (CPred(DVar.CKind))
595  return DVar;
596  }
597  return DSAVarData();
598 }
599 
600 template <class ClausesPredicate, class DirectivesPredicate>
601 DSAStackTy::DSAVarData
602 DSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
603  DirectivesPredicate DPred, bool FromParent) {
604  D = D->getCanonicalDecl();
605  auto StartI = std::next(Stack.rbegin());
606  auto EndI = std::prev(Stack.rend());
607  if (FromParent && StartI != EndI) {
608  StartI = std::next(StartI);
609  }
610  for (auto I = StartI, EE = EndI; I != EE; ++I) {
611  if (!DPred(I->Directive))
612  break;
613  DSAVarData DVar = getDSA(I, D);
614  if (CPred(DVar.CKind))
615  return DVar;
616  return DSAVarData();
617  }
618  return DSAVarData();
619 }
620 
621 bool DSAStackTy::hasExplicitDSA(
622  VarDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
623  unsigned Level) {
624  if (CPred(ClauseKindMode))
625  return true;
626  if (isClauseParsingMode())
627  ++Level;
628  D = D->getCanonicalDecl();
629  auto StartI = Stack.rbegin();
630  auto EndI = std::prev(Stack.rend());
631  if (std::distance(StartI, EndI) <= (int)Level)
632  return false;
633  std::advance(StartI, Level);
634  return (StartI->SharingMap.count(D) > 0) && StartI->SharingMap[D].RefExpr &&
635  CPred(StartI->SharingMap[D].Attributes);
636 }
637 
638 template <class NamedDirectivesPredicate>
639 bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) {
640  auto StartI = std::next(Stack.rbegin());
641  auto EndI = std::prev(Stack.rend());
642  if (FromParent && StartI != EndI) {
643  StartI = std::next(StartI);
644  }
645  for (auto I = StartI, EE = EndI; I != EE; ++I) {
646  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
647  return true;
648  }
649  return false;
650 }
651 
652 void Sema::InitDataSharingAttributesStack() {
653  VarDataSharingAttributesStack = new DSAStackTy(*this);
654 }
655 
656 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
657 
659  assert(LangOpts.OpenMP && "OpenMP is not allowed");
660  VD = VD->getCanonicalDecl();
661  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
662  (!DSAStack->isClauseParsingMode() ||
663  DSAStack->getParentDirective() != OMPD_unknown)) {
664  if (DSAStack->isLoopControlVariable(VD) ||
665  (VD->hasLocalStorage() &&
666  isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
667  DSAStack->isForceVarCapturing())
668  return true;
669  auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isClauseParsingMode());
670  if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
671  return true;
672  DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(),
673  DSAStack->isClauseParsingMode());
674  return DVarPrivate.CKind != OMPC_unknown;
675  }
676  return false;
677 }
678 
679 bool Sema::isOpenMPPrivateVar(VarDecl *VD, unsigned Level) {
680  assert(LangOpts.OpenMP && "OpenMP is not allowed");
681  return DSAStack->hasExplicitDSA(
682  VD, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level);
683 }
684 
685 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
686 
688  const DeclarationNameInfo &DirName,
689  Scope *CurScope, SourceLocation Loc) {
690  DSAStack->push(DKind, DirName, CurScope, Loc);
692 }
693 
695  DSAStack->setClauseParsingMode(K);
696 }
697 
699  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
700 }
701 
702 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
703  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
704  // A variable of class type (or array thereof) that appears in a lastprivate
705  // clause requires an accessible, unambiguous default constructor for the
706  // class type, unless the list item is also specified in a firstprivate
707  // clause.
708  if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
709  for (auto *C : D->clauses()) {
710  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
711  SmallVector<Expr *, 8> PrivateCopies;
712  for (auto *DE : Clause->varlists()) {
713  if (DE->isValueDependent() || DE->isTypeDependent()) {
714  PrivateCopies.push_back(nullptr);
715  continue;
716  }
717  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(DE)->getDecl());
718  QualType Type = VD->getType();
719  auto DVar = DSAStack->getTopDSA(VD, false);
720  if (DVar.CKind == OMPC_lastprivate) {
721  // Generate helper private variable and initialize it with the
722  // default value. The address of the original variable is replaced
723  // by the address of the new private variable in CodeGen. This new
724  // variable is not added to IdResolver, so the code in the OpenMP
725  // region uses original variable for proper diagnostics.
726  auto *VDPrivate =
727  buildVarDecl(*this, DE->getExprLoc(), Type.getUnqualifiedType(),
728  VD->getName());
729  ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
730  if (VDPrivate->isInvalidDecl())
731  continue;
732  PrivateCopies.push_back(buildDeclRefExpr(
733  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
734  } else {
735  // The variable is also a firstprivate, so initialization sequence
736  // for private copy is generated already.
737  PrivateCopies.push_back(nullptr);
738  }
739  }
740  // Set initializers to private copies if no errors were found.
741  if (PrivateCopies.size() == Clause->varlist_size()) {
742  Clause->setPrivateCopies(PrivateCopies);
743  }
744  }
745  }
746  }
747 
748  DSAStack->pop();
751 }
752 
753 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
754  Expr *NumIterations, Sema &SemaRef,
755  Scope *S);
756 
757 namespace {
758 
759 class VarDeclFilterCCC : public CorrectionCandidateCallback {
760 private:
761  Sema &SemaRef;
762 
763 public:
764  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
765  bool ValidateCandidate(const TypoCorrection &Candidate) override {
766  NamedDecl *ND = Candidate.getCorrectionDecl();
767  if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
768  return VD->hasGlobalStorage() &&
769  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
770  SemaRef.getCurScope());
771  }
772  return false;
773  }
774 };
775 } // namespace
776 
778  CXXScopeSpec &ScopeSpec,
779  const DeclarationNameInfo &Id) {
780  LookupResult Lookup(*this, Id, LookupOrdinaryName);
781  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
782 
783  if (Lookup.isAmbiguous())
784  return ExprError();
785 
786  VarDecl *VD;
787  if (!Lookup.isSingleResult()) {
788  if (TypoCorrection Corrected = CorrectTypo(
789  Id, LookupOrdinaryName, CurScope, nullptr,
790  llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
791  diagnoseTypo(Corrected,
792  PDiag(Lookup.empty()
793  ? diag::err_undeclared_var_use_suggest
794  : diag::err_omp_expected_var_arg_suggest)
795  << Id.getName());
796  VD = Corrected.getCorrectionDeclAs<VarDecl>();
797  } else {
798  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
799  : diag::err_omp_expected_var_arg)
800  << Id.getName();
801  return ExprError();
802  }
803  } else {
804  if (!(VD = Lookup.getAsSingle<VarDecl>())) {
805  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
806  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
807  return ExprError();
808  }
809  }
810  Lookup.suppressDiagnostics();
811 
812  // OpenMP [2.9.2, Syntax, C/C++]
813  // Variables must be file-scope, namespace-scope, or static block-scope.
814  if (!VD->hasGlobalStorage()) {
815  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
816  << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
817  bool IsDecl =
819  Diag(VD->getLocation(),
820  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
821  << VD;
822  return ExprError();
823  }
824 
825  VarDecl *CanonicalVD = VD->getCanonicalDecl();
826  NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
827  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
828  // A threadprivate directive for file-scope variables must appear outside
829  // any definition or declaration.
830  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
832  Diag(Id.getLoc(), diag::err_omp_var_scope)
833  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
834  bool IsDecl =
836  Diag(VD->getLocation(),
837  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
838  << VD;
839  return ExprError();
840  }
841  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
842  // A threadprivate directive for static class member variables must appear
843  // in the class definition, in the same scope in which the member
844  // variables are declared.
845  if (CanonicalVD->isStaticDataMember() &&
846  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
847  Diag(Id.getLoc(), diag::err_omp_var_scope)
848  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
849  bool IsDecl =
851  Diag(VD->getLocation(),
852  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
853  << VD;
854  return ExprError();
855  }
856  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
857  // A threadprivate directive for namespace-scope variables must appear
858  // outside any definition or declaration other than the namespace
859  // definition itself.
860  if (CanonicalVD->getDeclContext()->isNamespace() &&
862  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
863  Diag(Id.getLoc(), diag::err_omp_var_scope)
864  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
865  bool IsDecl =
867  Diag(VD->getLocation(),
868  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
869  << VD;
870  return ExprError();
871  }
872  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
873  // A threadprivate directive for static block-scope variables must appear
874  // in the scope of the variable and not in a nested scope.
875  if (CanonicalVD->isStaticLocal() && CurScope &&
876  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
877  Diag(Id.getLoc(), diag::err_omp_var_scope)
878  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
879  bool IsDecl =
881  Diag(VD->getLocation(),
882  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
883  << VD;
884  return ExprError();
885  }
886 
887  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
888  // A threadprivate directive must lexically precede all references to any
889  // of the variables in its list.
890  if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
891  Diag(Id.getLoc(), diag::err_omp_var_used)
892  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
893  return ExprError();
894  }
895 
896  QualType ExprType = VD->getType().getNonReferenceType();
897  ExprResult DE = buildDeclRefExpr(*this, VD, ExprType, Id.getLoc());
898  return DE;
899 }
900 
903  ArrayRef<Expr *> VarList) {
904  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
905  CurContext->addDecl(D);
907  }
908  return DeclGroupPtrTy();
909 }
910 
911 namespace {
912 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
913  Sema &SemaRef;
914 
915 public:
916  bool VisitDeclRefExpr(const DeclRefExpr *E) {
917  if (auto VD = dyn_cast<VarDecl>(E->getDecl())) {
918  if (VD->hasLocalStorage()) {
919  SemaRef.Diag(E->getLocStart(),
920  diag::err_omp_local_var_in_threadprivate_init)
921  << E->getSourceRange();
922  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
923  << VD << VD->getSourceRange();
924  return true;
925  }
926  }
927  return false;
928  }
929  bool VisitStmt(const Stmt *S) {
930  for (auto Child : S->children()) {
931  if (Child && Visit(Child))
932  return true;
933  }
934  return false;
935  }
936  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
937 };
938 } // namespace
939 
943  for (auto &RefExpr : VarList) {
944  DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
945  VarDecl *VD = cast<VarDecl>(DE->getDecl());
946  SourceLocation ILoc = DE->getExprLoc();
947 
948  QualType QType = VD->getType();
949  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
950  // It will be analyzed later.
951  Vars.push_back(DE);
952  continue;
953  }
954 
955  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
956  // A threadprivate variable must not have an incomplete type.
957  if (RequireCompleteType(ILoc, VD->getType(),
958  diag::err_omp_threadprivate_incomplete_type)) {
959  continue;
960  }
961 
962  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
963  // A threadprivate variable must not have a reference type.
964  if (VD->getType()->isReferenceType()) {
965  Diag(ILoc, diag::err_omp_ref_type_arg)
966  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
967  bool IsDecl =
968  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
969  Diag(VD->getLocation(),
970  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
971  << VD;
972  continue;
973  }
974 
975  // Check if this is a TLS variable. If TLS is not being supported, produce
976  // the corresponding diagnostic.
977  if ((VD->getTLSKind() != VarDecl::TLS_None &&
978  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
979  getLangOpts().OpenMPUseTLS &&
981  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
982  !VD->isLocalVarDecl())) {
983  Diag(ILoc, diag::err_omp_var_thread_local)
984  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
985  bool IsDecl =
986  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
987  Diag(VD->getLocation(),
988  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
989  << VD;
990  continue;
991  }
992 
993  // Check if initial value of threadprivate variable reference variable with
994  // local storage (it is not supported by runtime).
995  if (auto Init = VD->getAnyInitializer()) {
996  LocalVarRefChecker Checker(*this);
997  if (Checker.Visit(Init))
998  continue;
999  }
1000 
1001  Vars.push_back(RefExpr);
1002  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1003  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1004  Context, SourceRange(Loc, Loc)));
1005  if (auto *ML = Context.getASTMutationListener())
1006  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1007  }
1008  OMPThreadPrivateDecl *D = nullptr;
1009  if (!Vars.empty()) {
1011  Vars);
1012  D->setAccess(AS_public);
1013  }
1014  return D;
1015 }
1016 
1017 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1018  const VarDecl *VD, DSAStackTy::DSAVarData DVar,
1019  bool IsLoopIterVar = false) {
1020  if (DVar.RefExpr) {
1021  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1022  << getOpenMPClauseName(DVar.CKind);
1023  return;
1024  }
1025  enum {
1026  PDSA_StaticMemberShared,
1027  PDSA_StaticLocalVarShared,
1028  PDSA_LoopIterVarPrivate,
1029  PDSA_LoopIterVarLinear,
1030  PDSA_LoopIterVarLastprivate,
1031  PDSA_ConstVarShared,
1032  PDSA_GlobalVarShared,
1033  PDSA_TaskVarFirstprivate,
1034  PDSA_LocalVarPrivate,
1035  PDSA_Implicit
1036  } Reason = PDSA_Implicit;
1037  bool ReportHint = false;
1038  auto ReportLoc = VD->getLocation();
1039  if (IsLoopIterVar) {
1040  if (DVar.CKind == OMPC_private)
1041  Reason = PDSA_LoopIterVarPrivate;
1042  else if (DVar.CKind == OMPC_lastprivate)
1043  Reason = PDSA_LoopIterVarLastprivate;
1044  else
1045  Reason = PDSA_LoopIterVarLinear;
1046  } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) {
1047  Reason = PDSA_TaskVarFirstprivate;
1048  ReportLoc = DVar.ImplicitDSALoc;
1049  } else if (VD->isStaticLocal())
1050  Reason = PDSA_StaticLocalVarShared;
1051  else if (VD->isStaticDataMember())
1052  Reason = PDSA_StaticMemberShared;
1053  else if (VD->isFileVarDecl())
1054  Reason = PDSA_GlobalVarShared;
1055  else if (VD->getType().isConstant(SemaRef.getASTContext()))
1056  Reason = PDSA_ConstVarShared;
1057  else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1058  ReportHint = true;
1059  Reason = PDSA_LocalVarPrivate;
1060  }
1061  if (Reason != PDSA_Implicit) {
1062  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1063  << Reason << ReportHint
1064  << getOpenMPDirectiveName(Stack->getCurrentDirective());
1065  } else if (DVar.ImplicitDSALoc.isValid()) {
1066  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1067  << getOpenMPClauseName(DVar.CKind);
1068  }
1069 }
1070 
1071 namespace {
1072 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1073  DSAStackTy *Stack;
1074  Sema &SemaRef;
1075  bool ErrorFound;
1076  CapturedStmt *CS;
1077  llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1078  llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
1079 
1080 public:
1081  void VisitDeclRefExpr(DeclRefExpr *E) {
1082  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1083  // Skip internally declared variables.
1084  if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
1085  return;
1086 
1087  auto DVar = Stack->getTopDSA(VD, false);
1088  // Check if the variable has explicit DSA set and stop analysis if it so.
1089  if (DVar.RefExpr) return;
1090 
1091  auto ELoc = E->getExprLoc();
1092  auto DKind = Stack->getCurrentDirective();
1093  // The default(none) clause requires that each variable that is referenced
1094  // in the construct, and does not have a predetermined data-sharing
1095  // attribute, must have its data-sharing attribute explicitly determined
1096  // by being listed in a data-sharing attribute clause.
1097  if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1098  isParallelOrTaskRegion(DKind) &&
1099  VarsWithInheritedDSA.count(VD) == 0) {
1100  VarsWithInheritedDSA[VD] = E;
1101  return;
1102  }
1103 
1104  // OpenMP [2.9.3.6, Restrictions, p.2]
1105  // A list item that appears in a reduction clause of the innermost
1106  // enclosing worksharing or parallel construct may not be accessed in an
1107  // explicit task.
1108  DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
1109  [](OpenMPDirectiveKind K) -> bool {
1110  return isOpenMPParallelDirective(K) ||
1113  },
1114  false);
1115  if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) {
1116  ErrorFound = true;
1117  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1118  ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1119  return;
1120  }
1121 
1122  // Define implicit data-sharing attributes for task.
1123  DVar = Stack->getImplicitDSA(VD, false);
1124  if (DKind == OMPD_task && DVar.CKind != OMPC_shared)
1125  ImplicitFirstprivate.push_back(E);
1126  }
1127  }
1128  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
1129  for (auto *C : S->clauses()) {
1130  // Skip analysis of arguments of implicitly defined firstprivate clause
1131  // for task directives.
1132  if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid()))
1133  for (auto *CC : C->children()) {
1134  if (CC)
1135  Visit(CC);
1136  }
1137  }
1138  }
1139  void VisitStmt(Stmt *S) {
1140  for (auto *C : S->children()) {
1141  if (C && !isa<OMPExecutableDirective>(C))
1142  Visit(C);
1143  }
1144  }
1145 
1146  bool isErrorFound() { return ErrorFound; }
1147  ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
1148  llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() {
1149  return VarsWithInheritedDSA;
1150  }
1151 
1152  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
1153  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
1154 };
1155 } // namespace
1156 
1158  switch (DKind) {
1159  case OMPD_parallel: {
1160  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1161  QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
1162  Sema::CapturedParamNameType Params[] = {
1163  std::make_pair(".global_tid.", KmpInt32PtrTy),
1164  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1165  std::make_pair(StringRef(), QualType()) // __context with shared vars
1166  };
1167  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1168  Params);
1169  break;
1170  }
1171  case OMPD_simd: {
1172  Sema::CapturedParamNameType Params[] = {
1173  std::make_pair(StringRef(), QualType()) // __context with shared vars
1174  };
1175  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1176  Params);
1177  break;
1178  }
1179  case OMPD_for: {
1180  Sema::CapturedParamNameType Params[] = {
1181  std::make_pair(StringRef(), QualType()) // __context with shared vars
1182  };
1183  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1184  Params);
1185  break;
1186  }
1187  case OMPD_for_simd: {
1188  Sema::CapturedParamNameType Params[] = {
1189  std::make_pair(StringRef(), QualType()) // __context with shared vars
1190  };
1191  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1192  Params);
1193  break;
1194  }
1195  case OMPD_sections: {
1196  Sema::CapturedParamNameType Params[] = {
1197  std::make_pair(StringRef(), QualType()) // __context with shared vars
1198  };
1199  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1200  Params);
1201  break;
1202  }
1203  case OMPD_section: {
1204  Sema::CapturedParamNameType Params[] = {
1205  std::make_pair(StringRef(), QualType()) // __context with shared vars
1206  };
1207  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1208  Params);
1209  break;
1210  }
1211  case OMPD_single: {
1212  Sema::CapturedParamNameType Params[] = {
1213  std::make_pair(StringRef(), QualType()) // __context with shared vars
1214  };
1215  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1216  Params);
1217  break;
1218  }
1219  case OMPD_master: {
1220  Sema::CapturedParamNameType Params[] = {
1221  std::make_pair(StringRef(), QualType()) // __context with shared vars
1222  };
1223  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1224  Params);
1225  break;
1226  }
1227  case OMPD_critical: {
1228  Sema::CapturedParamNameType Params[] = {
1229  std::make_pair(StringRef(), QualType()) // __context with shared vars
1230  };
1231  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1232  Params);
1233  break;
1234  }
1235  case OMPD_parallel_for: {
1236  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1237  QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
1238  Sema::CapturedParamNameType Params[] = {
1239  std::make_pair(".global_tid.", KmpInt32PtrTy),
1240  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1241  std::make_pair(StringRef(), QualType()) // __context with shared vars
1242  };
1243  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1244  Params);
1245  break;
1246  }
1247  case OMPD_parallel_for_simd: {
1248  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1249  QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
1250  Sema::CapturedParamNameType Params[] = {
1251  std::make_pair(".global_tid.", KmpInt32PtrTy),
1252  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1253  std::make_pair(StringRef(), QualType()) // __context with shared vars
1254  };
1255  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1256  Params);
1257  break;
1258  }
1259  case OMPD_parallel_sections: {
1260  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1261  QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
1262  Sema::CapturedParamNameType Params[] = {
1263  std::make_pair(".global_tid.", KmpInt32PtrTy),
1264  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1265  std::make_pair(StringRef(), QualType()) // __context with shared vars
1266  };
1267  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1268  Params);
1269  break;
1270  }
1271  case OMPD_task: {
1272  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1275  EPI.Variadic = true;
1276  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
1277  Sema::CapturedParamNameType Params[] = {
1278  std::make_pair(".global_tid.", KmpInt32Ty),
1279  std::make_pair(".part_id.", KmpInt32Ty),
1280  std::make_pair(".privates.",
1282  std::make_pair(
1283  ".copy_fn.",
1284  Context.getPointerType(CopyFnType).withConst().withRestrict()),
1285  std::make_pair(StringRef(), QualType()) // __context with shared vars
1286  };
1287  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1288  Params);
1289  // Mark this captured region as inlined, because we don't use outlined
1290  // function directly.
1292  AlwaysInlineAttr::CreateImplicit(
1293  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
1294  break;
1295  }
1296  case OMPD_ordered: {
1297  Sema::CapturedParamNameType Params[] = {
1298  std::make_pair(StringRef(), QualType()) // __context with shared vars
1299  };
1300  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1301  Params);
1302  break;
1303  }
1304  case OMPD_atomic: {
1305  Sema::CapturedParamNameType Params[] = {
1306  std::make_pair(StringRef(), QualType()) // __context with shared vars
1307  };
1308  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1309  Params);
1310  break;
1311  }
1312  case OMPD_target: {
1313  Sema::CapturedParamNameType Params[] = {
1314  std::make_pair(StringRef(), QualType()) // __context with shared vars
1315  };
1316  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1317  Params);
1318  break;
1319  }
1320  case OMPD_teams: {
1321  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
1322  QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
1323  Sema::CapturedParamNameType Params[] = {
1324  std::make_pair(".global_tid.", KmpInt32PtrTy),
1325  std::make_pair(".bound_tid.", KmpInt32PtrTy),
1326  std::make_pair(StringRef(), QualType()) // __context with shared vars
1327  };
1328  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1329  Params);
1330  break;
1331  }
1332  case OMPD_taskgroup: {
1333  Sema::CapturedParamNameType Params[] = {
1334  std::make_pair(StringRef(), QualType()) // __context with shared vars
1335  };
1336  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
1337  Params);
1338  break;
1339  }
1340  case OMPD_threadprivate:
1341  case OMPD_taskyield:
1342  case OMPD_barrier:
1343  case OMPD_taskwait:
1344  case OMPD_cancellation_point:
1345  case OMPD_cancel:
1346  case OMPD_flush:
1347  llvm_unreachable("OpenMP Directive is not allowed");
1348  case OMPD_unknown:
1349  llvm_unreachable("Unknown OpenMP directive");
1350  }
1351 }
1352 
1354  ArrayRef<OMPClause *> Clauses) {
1355  if (!S.isUsable()) {
1357  return StmtError();
1358  }
1359  // This is required for proper codegen.
1360  for (auto *Clause : Clauses) {
1361  if (isOpenMPPrivate(Clause->getClauseKind()) ||
1362  Clause->getClauseKind() == OMPC_copyprivate ||
1363  (getLangOpts().OpenMPUseTLS &&
1365  Clause->getClauseKind() == OMPC_copyin)) {
1366  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
1367  // Mark all variables in private list clauses as used in inner region.
1368  for (auto *VarRef : Clause->children()) {
1369  if (auto *E = cast_or_null<Expr>(VarRef)) {
1371  }
1372  }
1373  DSAStack->setForceVarCapturing(/*V=*/false);
1374  } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) &&
1375  Clause->getClauseKind() == OMPC_schedule) {
1376  // Mark all variables in private list clauses as used in inner region.
1377  // Required for proper codegen of combined directives.
1378  // TODO: add processing for other clauses.
1379  if (auto *E = cast_or_null<Expr>(
1380  cast<OMPScheduleClause>(Clause)->getHelperChunkSize())) {
1382  }
1383  }
1384  }
1385  return ActOnCapturedRegionEnd(S.get());
1386 }
1387 
1388 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
1389  OpenMPDirectiveKind CurrentRegion,
1390  const DeclarationNameInfo &CurrentName,
1391  OpenMPDirectiveKind CancelRegion,
1392  SourceLocation StartLoc) {
1393  // Allowed nesting of constructs
1394  // +------------------+-----------------+------------------------------------+
1395  // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)|
1396  // +------------------+-----------------+------------------------------------+
1397  // | parallel | parallel | * |
1398  // | parallel | for | * |
1399  // | parallel | for simd | * |
1400  // | parallel | master | * |
1401  // | parallel | critical | * |
1402  // | parallel | simd | * |
1403  // | parallel | sections | * |
1404  // | parallel | section | + |
1405  // | parallel | single | * |
1406  // | parallel | parallel for | * |
1407  // | parallel |parallel for simd| * |
1408  // | parallel |parallel sections| * |
1409  // | parallel | task | * |
1410  // | parallel | taskyield | * |
1411  // | parallel | barrier | * |
1412  // | parallel | taskwait | * |
1413  // | parallel | taskgroup | * |
1414  // | parallel | flush | * |
1415  // | parallel | ordered | + |
1416  // | parallel | atomic | * |
1417  // | parallel | target | * |
1418  // | parallel | teams | + |
1419  // | parallel | cancellation | |
1420  // | | point | ! |
1421  // | parallel | cancel | ! |
1422  // +------------------+-----------------+------------------------------------+
1423  // | for | parallel | * |
1424  // | for | for | + |
1425  // | for | for simd | + |
1426  // | for | master | + |
1427  // | for | critical | * |
1428  // | for | simd | * |
1429  // | for | sections | + |
1430  // | for | section | + |
1431  // | for | single | + |
1432  // | for | parallel for | * |
1433  // | for |parallel for simd| * |
1434  // | for |parallel sections| * |
1435  // | for | task | * |
1436  // | for | taskyield | * |
1437  // | for | barrier | + |
1438  // | for | taskwait | * |
1439  // | for | taskgroup | * |
1440  // | for | flush | * |
1441  // | for | ordered | * (if construct is ordered) |
1442  // | for | atomic | * |
1443  // | for | target | * |
1444  // | for | teams | + |
1445  // | for | cancellation | |
1446  // | | point | ! |
1447  // | for | cancel | ! |
1448  // +------------------+-----------------+------------------------------------+
1449  // | master | parallel | * |
1450  // | master | for | + |
1451  // | master | for simd | + |
1452  // | master | master | * |
1453  // | master | critical | * |
1454  // | master | simd | * |
1455  // | master | sections | + |
1456  // | master | section | + |
1457  // | master | single | + |
1458  // | master | parallel for | * |
1459  // | master |parallel for simd| * |
1460  // | master |parallel sections| * |
1461  // | master | task | * |
1462  // | master | taskyield | * |
1463  // | master | barrier | + |
1464  // | master | taskwait | * |
1465  // | master | taskgroup | * |
1466  // | master | flush | * |
1467  // | master | ordered | + |
1468  // | master | atomic | * |
1469  // | master | target | * |
1470  // | master | teams | + |
1471  // | master | cancellation | |
1472  // | | point | |
1473  // | master | cancel | |
1474  // +------------------+-----------------+------------------------------------+
1475  // | critical | parallel | * |
1476  // | critical | for | + |
1477  // | critical | for simd | + |
1478  // | critical | master | * |
1479  // | critical | critical | * (should have different names) |
1480  // | critical | simd | * |
1481  // | critical | sections | + |
1482  // | critical | section | + |
1483  // | critical | single | + |
1484  // | critical | parallel for | * |
1485  // | critical |parallel for simd| * |
1486  // | critical |parallel sections| * |
1487  // | critical | task | * |
1488  // | critical | taskyield | * |
1489  // | critical | barrier | + |
1490  // | critical | taskwait | * |
1491  // | critical | taskgroup | * |
1492  // | critical | ordered | + |
1493  // | critical | atomic | * |
1494  // | critical | target | * |
1495  // | critical | teams | + |
1496  // | critical | cancellation | |
1497  // | | point | |
1498  // | critical | cancel | |
1499  // +------------------+-----------------+------------------------------------+
1500  // | simd | parallel | |
1501  // | simd | for | |
1502  // | simd | for simd | |
1503  // | simd | master | |
1504  // | simd | critical | |
1505  // | simd | simd | |
1506  // | simd | sections | |
1507  // | simd | section | |
1508  // | simd | single | |
1509  // | simd | parallel for | |
1510  // | simd |parallel for simd| |
1511  // | simd |parallel sections| |
1512  // | simd | task | |
1513  // | simd | taskyield | |
1514  // | simd | barrier | |
1515  // | simd | taskwait | |
1516  // | simd | taskgroup | |
1517  // | simd | flush | |
1518  // | simd | ordered | |
1519  // | simd | atomic | |
1520  // | simd | target | |
1521  // | simd | teams | |
1522  // | simd | cancellation | |
1523  // | | point | |
1524  // | simd | cancel | |
1525  // +------------------+-----------------+------------------------------------+
1526  // | for simd | parallel | |
1527  // | for simd | for | |
1528  // | for simd | for simd | |
1529  // | for simd | master | |
1530  // | for simd | critical | |
1531  // | for simd | simd | |
1532  // | for simd | sections | |
1533  // | for simd | section | |
1534  // | for simd | single | |
1535  // | for simd | parallel for | |
1536  // | for simd |parallel for simd| |
1537  // | for simd |parallel sections| |
1538  // | for simd | task | |
1539  // | for simd | taskyield | |
1540  // | for simd | barrier | |
1541  // | for simd | taskwait | |
1542  // | for simd | taskgroup | |
1543  // | for simd | flush | |
1544  // | for simd | ordered | |
1545  // | for simd | atomic | |
1546  // | for simd | target | |
1547  // | for simd | teams | |
1548  // | for simd | cancellation | |
1549  // | | point | |
1550  // | for simd | cancel | |
1551  // +------------------+-----------------+------------------------------------+
1552  // | parallel for simd| parallel | |
1553  // | parallel for simd| for | |
1554  // | parallel for simd| for simd | |
1555  // | parallel for simd| master | |
1556  // | parallel for simd| critical | |
1557  // | parallel for simd| simd | |
1558  // | parallel for simd| sections | |
1559  // | parallel for simd| section | |
1560  // | parallel for simd| single | |
1561  // | parallel for simd| parallel for | |
1562  // | parallel for simd|parallel for simd| |
1563  // | parallel for simd|parallel sections| |
1564  // | parallel for simd| task | |
1565  // | parallel for simd| taskyield | |
1566  // | parallel for simd| barrier | |
1567  // | parallel for simd| taskwait | |
1568  // | parallel for simd| taskgroup | |
1569  // | parallel for simd| flush | |
1570  // | parallel for simd| ordered | |
1571  // | parallel for simd| atomic | |
1572  // | parallel for simd| target | |
1573  // | parallel for simd| teams | |
1574  // | parallel for simd| cancellation | |
1575  // | | point | |
1576  // | parallel for simd| cancel | |
1577  // +------------------+-----------------+------------------------------------+
1578  // | sections | parallel | * |
1579  // | sections | for | + |
1580  // | sections | for simd | + |
1581  // | sections | master | + |
1582  // | sections | critical | * |
1583  // | sections | simd | * |
1584  // | sections | sections | + |
1585  // | sections | section | * |
1586  // | sections | single | + |
1587  // | sections | parallel for | * |
1588  // | sections |parallel for simd| * |
1589  // | sections |parallel sections| * |
1590  // | sections | task | * |
1591  // | sections | taskyield | * |
1592  // | sections | barrier | + |
1593  // | sections | taskwait | * |
1594  // | sections | taskgroup | * |
1595  // | sections | flush | * |
1596  // | sections | ordered | + |
1597  // | sections | atomic | * |
1598  // | sections | target | * |
1599  // | sections | teams | + |
1600  // | sections | cancellation | |
1601  // | | point | ! |
1602  // | sections | cancel | ! |
1603  // +------------------+-----------------+------------------------------------+
1604  // | section | parallel | * |
1605  // | section | for | + |
1606  // | section | for simd | + |
1607  // | section | master | + |
1608  // | section | critical | * |
1609  // | section | simd | * |
1610  // | section | sections | + |
1611  // | section | section | + |
1612  // | section | single | + |
1613  // | section | parallel for | * |
1614  // | section |parallel for simd| * |
1615  // | section |parallel sections| * |
1616  // | section | task | * |
1617  // | section | taskyield | * |
1618  // | section | barrier | + |
1619  // | section | taskwait | * |
1620  // | section | taskgroup | * |
1621  // | section | flush | * |
1622  // | section | ordered | + |
1623  // | section | atomic | * |
1624  // | section | target | * |
1625  // | section | teams | + |
1626  // | section | cancellation | |
1627  // | | point | ! |
1628  // | section | cancel | ! |
1629  // +------------------+-----------------+------------------------------------+
1630  // | single | parallel | * |
1631  // | single | for | + |
1632  // | single | for simd | + |
1633  // | single | master | + |
1634  // | single | critical | * |
1635  // | single | simd | * |
1636  // | single | sections | + |
1637  // | single | section | + |
1638  // | single | single | + |
1639  // | single | parallel for | * |
1640  // | single |parallel for simd| * |
1641  // | single |parallel sections| * |
1642  // | single | task | * |
1643  // | single | taskyield | * |
1644  // | single | barrier | + |
1645  // | single | taskwait | * |
1646  // | single | taskgroup | * |
1647  // | single | flush | * |
1648  // | single | ordered | + |
1649  // | single | atomic | * |
1650  // | single | target | * |
1651  // | single | teams | + |
1652  // | single | cancellation | |
1653  // | | point | |
1654  // | single | cancel | |
1655  // +------------------+-----------------+------------------------------------+
1656  // | parallel for | parallel | * |
1657  // | parallel for | for | + |
1658  // | parallel for | for simd | + |
1659  // | parallel for | master | + |
1660  // | parallel for | critical | * |
1661  // | parallel for | simd | * |
1662  // | parallel for | sections | + |
1663  // | parallel for | section | + |
1664  // | parallel for | single | + |
1665  // | parallel for | parallel for | * |
1666  // | parallel for |parallel for simd| * |
1667  // | parallel for |parallel sections| * |
1668  // | parallel for | task | * |
1669  // | parallel for | taskyield | * |
1670  // | parallel for | barrier | + |
1671  // | parallel for | taskwait | * |
1672  // | parallel for | taskgroup | * |
1673  // | parallel for | flush | * |
1674  // | parallel for | ordered | * (if construct is ordered) |
1675  // | parallel for | atomic | * |
1676  // | parallel for | target | * |
1677  // | parallel for | teams | + |
1678  // | parallel for | cancellation | |
1679  // | | point | ! |
1680  // | parallel for | cancel | ! |
1681  // +------------------+-----------------+------------------------------------+
1682  // | parallel sections| parallel | * |
1683  // | parallel sections| for | + |
1684  // | parallel sections| for simd | + |
1685  // | parallel sections| master | + |
1686  // | parallel sections| critical | + |
1687  // | parallel sections| simd | * |
1688  // | parallel sections| sections | + |
1689  // | parallel sections| section | * |
1690  // | parallel sections| single | + |
1691  // | parallel sections| parallel for | * |
1692  // | parallel sections|parallel for simd| * |
1693  // | parallel sections|parallel sections| * |
1694  // | parallel sections| task | * |
1695  // | parallel sections| taskyield | * |
1696  // | parallel sections| barrier | + |
1697  // | parallel sections| taskwait | * |
1698  // | parallel sections| taskgroup | * |
1699  // | parallel sections| flush | * |
1700  // | parallel sections| ordered | + |
1701  // | parallel sections| atomic | * |
1702  // | parallel sections| target | * |
1703  // | parallel sections| teams | + |
1704  // | parallel sections| cancellation | |
1705  // | | point | ! |
1706  // | parallel sections| cancel | ! |
1707  // +------------------+-----------------+------------------------------------+
1708  // | task | parallel | * |
1709  // | task | for | + |
1710  // | task | for simd | + |
1711  // | task | master | + |
1712  // | task | critical | * |
1713  // | task | simd | * |
1714  // | task | sections | + |
1715  // | task | section | + |
1716  // | task | single | + |
1717  // | task | parallel for | * |
1718  // | task |parallel for simd| * |
1719  // | task |parallel sections| * |
1720  // | task | task | * |
1721  // | task | taskyield | * |
1722  // | task | barrier | + |
1723  // | task | taskwait | * |
1724  // | task | taskgroup | * |
1725  // | task | flush | * |
1726  // | task | ordered | + |
1727  // | task | atomic | * |
1728  // | task | target | * |
1729  // | task | teams | + |
1730  // | task | cancellation | |
1731  // | | point | ! |
1732  // | task | cancel | ! |
1733  // +------------------+-----------------+------------------------------------+
1734  // | ordered | parallel | * |
1735  // | ordered | for | + |
1736  // | ordered | for simd | + |
1737  // | ordered | master | * |
1738  // | ordered | critical | * |
1739  // | ordered | simd | * |
1740  // | ordered | sections | + |
1741  // | ordered | section | + |
1742  // | ordered | single | + |
1743  // | ordered | parallel for | * |
1744  // | ordered |parallel for simd| * |
1745  // | ordered |parallel sections| * |
1746  // | ordered | task | * |
1747  // | ordered | taskyield | * |
1748  // | ordered | barrier | + |
1749  // | ordered | taskwait | * |
1750  // | ordered | taskgroup | * |
1751  // | ordered | flush | * |
1752  // | ordered | ordered | + |
1753  // | ordered | atomic | * |
1754  // | ordered | target | * |
1755  // | ordered | teams | + |
1756  // | ordered | cancellation | |
1757  // | | point | |
1758  // | ordered | cancel | |
1759  // +------------------+-----------------+------------------------------------+
1760  // | atomic | parallel | |
1761  // | atomic | for | |
1762  // | atomic | for simd | |
1763  // | atomic | master | |
1764  // | atomic | critical | |
1765  // | atomic | simd | |
1766  // | atomic | sections | |
1767  // | atomic | section | |
1768  // | atomic | single | |
1769  // | atomic | parallel for | |
1770  // | atomic |parallel for simd| |
1771  // | atomic |parallel sections| |
1772  // | atomic | task | |
1773  // | atomic | taskyield | |
1774  // | atomic | barrier | |
1775  // | atomic | taskwait | |
1776  // | atomic | taskgroup | |
1777  // | atomic | flush | |
1778  // | atomic | ordered | |
1779  // | atomic | atomic | |
1780  // | atomic | target | |
1781  // | atomic | teams | |
1782  // | atomic | cancellation | |
1783  // | | point | |
1784  // | atomic | cancel | |
1785  // +------------------+-----------------+------------------------------------+
1786  // | target | parallel | * |
1787  // | target | for | * |
1788  // | target | for simd | * |
1789  // | target | master | * |
1790  // | target | critical | * |
1791  // | target | simd | * |
1792  // | target | sections | * |
1793  // | target | section | * |
1794  // | target | single | * |
1795  // | target | parallel for | * |
1796  // | target |parallel for simd| * |
1797  // | target |parallel sections| * |
1798  // | target | task | * |
1799  // | target | taskyield | * |
1800  // | target | barrier | * |
1801  // | target | taskwait | * |
1802  // | target | taskgroup | * |
1803  // | target | flush | * |
1804  // | target | ordered | * |
1805  // | target | atomic | * |
1806  // | target | target | * |
1807  // | target | teams | * |
1808  // | target | cancellation | |
1809  // | | point | |
1810  // | target | cancel | |
1811  // +------------------+-----------------+------------------------------------+
1812  // | teams | parallel | * |
1813  // | teams | for | + |
1814  // | teams | for simd | + |
1815  // | teams | master | + |
1816  // | teams | critical | + |
1817  // | teams | simd | + |
1818  // | teams | sections | + |
1819  // | teams | section | + |
1820  // | teams | single | + |
1821  // | teams | parallel for | * |
1822  // | teams |parallel for simd| * |
1823  // | teams |parallel sections| * |
1824  // | teams | task | + |
1825  // | teams | taskyield | + |
1826  // | teams | barrier | + |
1827  // | teams | taskwait | + |
1828  // | teams | taskgroup | + |
1829  // | teams | flush | + |
1830  // | teams | ordered | + |
1831  // | teams | atomic | + |
1832  // | teams | target | + |
1833  // | teams | teams | + |
1834  // | teams | cancellation | |
1835  // | | point | |
1836  // | teams | cancel | |
1837  // +------------------+-----------------+------------------------------------+
1838  if (Stack->getCurScope()) {
1839  auto ParentRegion = Stack->getParentDirective();
1840  bool NestingProhibited = false;
1841  bool CloseNesting = true;
1842  enum {
1843  NoRecommend,
1844  ShouldBeInParallelRegion,
1845  ShouldBeInOrderedRegion,
1846  ShouldBeInTargetRegion
1847  } Recommend = NoRecommend;
1848  if (isOpenMPSimdDirective(ParentRegion)) {
1849  // OpenMP [2.16, Nesting of Regions]
1850  // OpenMP constructs may not be nested inside a simd region.
1851  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
1852  return true;
1853  }
1854  if (ParentRegion == OMPD_atomic) {
1855  // OpenMP [2.16, Nesting of Regions]
1856  // OpenMP constructs may not be nested inside an atomic region.
1857  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
1858  return true;
1859  }
1860  if (CurrentRegion == OMPD_section) {
1861  // OpenMP [2.7.2, sections Construct, Restrictions]
1862  // Orphaned section directives are prohibited. That is, the section
1863  // directives must appear within the sections construct and must not be
1864  // encountered elsewhere in the sections region.
1865  if (ParentRegion != OMPD_sections &&
1866  ParentRegion != OMPD_parallel_sections) {
1867  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
1868  << (ParentRegion != OMPD_unknown)
1869  << getOpenMPDirectiveName(ParentRegion);
1870  return true;
1871  }
1872  return false;
1873  }
1874  // Allow some constructs to be orphaned (they could be used in functions,
1875  // called from OpenMP regions with the required preconditions).
1876  if (ParentRegion == OMPD_unknown)
1877  return false;
1878  if (CurrentRegion == OMPD_cancellation_point ||
1879  CurrentRegion == OMPD_cancel) {
1880  // OpenMP [2.16, Nesting of Regions]
1881  // A cancellation point construct for which construct-type-clause is
1882  // taskgroup must be nested inside a task construct. A cancellation
1883  // point construct for which construct-type-clause is not taskgroup must
1884  // be closely nested inside an OpenMP construct that matches the type
1885  // specified in construct-type-clause.
1886  // A cancel construct for which construct-type-clause is taskgroup must be
1887  // nested inside a task construct. A cancel construct for which
1888  // construct-type-clause is not taskgroup must be closely nested inside an
1889  // OpenMP construct that matches the type specified in
1890  // construct-type-clause.
1891  NestingProhibited =
1892  !((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) ||
1893  (CancelRegion == OMPD_for && ParentRegion == OMPD_for) ||
1894  (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
1895  (CancelRegion == OMPD_sections &&
1896  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections)));
1897  } else if (CurrentRegion == OMPD_master) {
1898  // OpenMP [2.16, Nesting of Regions]
1899  // A master region may not be closely nested inside a worksharing,
1900  // atomic, or explicit task region.
1901  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
1902  ParentRegion == OMPD_task;
1903  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
1904  // OpenMP [2.16, Nesting of Regions]
1905  // A critical region may not be nested (closely or otherwise) inside a
1906  // critical region with the same name. Note that this restriction is not
1907  // sufficient to prevent deadlock.
1908  SourceLocation PreviousCriticalLoc;
1909  bool DeadLock =
1910  Stack->hasDirective([CurrentName, &PreviousCriticalLoc](
1912  const DeclarationNameInfo &DNI,
1913  SourceLocation Loc)
1914  ->bool {
1915  if (K == OMPD_critical &&
1916  DNI.getName() == CurrentName.getName()) {
1917  PreviousCriticalLoc = Loc;
1918  return true;
1919  } else
1920  return false;
1921  },
1922  false /* skip top directive */);
1923  if (DeadLock) {
1924  SemaRef.Diag(StartLoc,
1925  diag::err_omp_prohibited_region_critical_same_name)
1926  << CurrentName.getName();
1927  if (PreviousCriticalLoc.isValid())
1928  SemaRef.Diag(PreviousCriticalLoc,
1929  diag::note_omp_previous_critical_region);
1930  return true;
1931  }
1932  } else if (CurrentRegion == OMPD_barrier) {
1933  // OpenMP [2.16, Nesting of Regions]
1934  // A barrier region may not be closely nested inside a worksharing,
1935  // explicit task, critical, ordered, atomic, or master region.
1936  NestingProhibited =
1937  isOpenMPWorksharingDirective(ParentRegion) ||
1938  ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
1939  ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
1940  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
1941  !isOpenMPParallelDirective(CurrentRegion)) {
1942  // OpenMP [2.16, Nesting of Regions]
1943  // A worksharing region may not be closely nested inside a worksharing,
1944  // explicit task, critical, ordered, atomic, or master region.
1945  NestingProhibited =
1946  isOpenMPWorksharingDirective(ParentRegion) ||
1947  ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
1948  ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
1949  Recommend = ShouldBeInParallelRegion;
1950  } else if (CurrentRegion == OMPD_ordered) {
1951  // OpenMP [2.16, Nesting of Regions]
1952  // An ordered region may not be closely nested inside a critical,
1953  // atomic, or explicit task region.
1954  // An ordered region must be closely nested inside a loop region (or
1955  // parallel loop region) with an ordered clause.
1956  NestingProhibited = ParentRegion == OMPD_critical ||
1957  ParentRegion == OMPD_task ||
1958  !Stack->isParentOrderedRegion();
1959  Recommend = ShouldBeInOrderedRegion;
1960  } else if (isOpenMPTeamsDirective(CurrentRegion)) {
1961  // OpenMP [2.16, Nesting of Regions]
1962  // If specified, a teams construct must be contained within a target
1963  // construct.
1964  NestingProhibited = ParentRegion != OMPD_target;
1965  Recommend = ShouldBeInTargetRegion;
1966  Stack->setParentTeamsRegionLoc(Stack->getConstructLoc());
1967  }
1968  if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) {
1969  // OpenMP [2.16, Nesting of Regions]
1970  // distribute, parallel, parallel sections, parallel workshare, and the
1971  // parallel loop and parallel loop SIMD constructs are the only OpenMP
1972  // constructs that can be closely nested in the teams region.
1973  // TODO: add distribute directive.
1974  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion);
1975  Recommend = ShouldBeInParallelRegion;
1976  }
1977  if (NestingProhibited) {
1978  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
1979  << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend
1980  << getOpenMPDirectiveName(CurrentRegion);
1981  return true;
1982  }
1983  }
1984  return false;
1985 }
1986 
1988  OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
1989  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
1990  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
1991  StmtResult Res = StmtError();
1992  if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
1993  StartLoc))
1994  return StmtError();
1995 
1996  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
1997  llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
1998  bool ErrorFound = false;
1999  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2000  if (AStmt) {
2001  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
2002 
2003  // Check default data sharing attributes for referenced variables.
2004  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
2005  DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
2006  if (DSAChecker.isErrorFound())
2007  return StmtError();
2008  // Generate list of implicitly defined firstprivate variables.
2009  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2010 
2011  if (!DSAChecker.getImplicitFirstprivate().empty()) {
2012  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2013  DSAChecker.getImplicitFirstprivate(), SourceLocation(),
2015  ClausesWithImplicit.push_back(Implicit);
2016  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2017  DSAChecker.getImplicitFirstprivate().size();
2018  } else
2019  ErrorFound = true;
2020  }
2021  }
2022 
2023  switch (Kind) {
2024  case OMPD_parallel:
2025  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
2026  EndLoc);
2027  break;
2028  case OMPD_simd:
2029  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2030  VarsWithInheritedDSA);
2031  break;
2032  case OMPD_for:
2033  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2034  VarsWithInheritedDSA);
2035  break;
2036  case OMPD_for_simd:
2037  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2038  EndLoc, VarsWithInheritedDSA);
2039  break;
2040  case OMPD_sections:
2041  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
2042  EndLoc);
2043  break;
2044  case OMPD_section:
2045  assert(ClausesWithImplicit.empty() &&
2046  "No clauses are allowed for 'omp section' directive");
2047  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
2048  break;
2049  case OMPD_single:
2050  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
2051  EndLoc);
2052  break;
2053  case OMPD_master:
2054  assert(ClausesWithImplicit.empty() &&
2055  "No clauses are allowed for 'omp master' directive");
2056  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
2057  break;
2058  case OMPD_critical:
2059  assert(ClausesWithImplicit.empty() &&
2060  "No clauses are allowed for 'omp critical' directive");
2061  Res = ActOnOpenMPCriticalDirective(DirName, AStmt, StartLoc, EndLoc);
2062  break;
2063  case OMPD_parallel_for:
2064  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
2065  EndLoc, VarsWithInheritedDSA);
2066  break;
2067  case OMPD_parallel_for_simd:
2069  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2070  break;
2071  case OMPD_parallel_sections:
2072  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
2073  StartLoc, EndLoc);
2074  break;
2075  case OMPD_task:
2076  Res =
2077  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2078  break;
2079  case OMPD_taskyield:
2080  assert(ClausesWithImplicit.empty() &&
2081  "No clauses are allowed for 'omp taskyield' directive");
2082  assert(AStmt == nullptr &&
2083  "No associated statement allowed for 'omp taskyield' directive");
2084  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
2085  break;
2086  case OMPD_barrier:
2087  assert(ClausesWithImplicit.empty() &&
2088  "No clauses are allowed for 'omp barrier' directive");
2089  assert(AStmt == nullptr &&
2090  "No associated statement allowed for 'omp barrier' directive");
2091  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
2092  break;
2093  case OMPD_taskwait:
2094  assert(ClausesWithImplicit.empty() &&
2095  "No clauses are allowed for 'omp taskwait' directive");
2096  assert(AStmt == nullptr &&
2097  "No associated statement allowed for 'omp taskwait' directive");
2098  Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
2099  break;
2100  case OMPD_taskgroup:
2101  assert(ClausesWithImplicit.empty() &&
2102  "No clauses are allowed for 'omp taskgroup' directive");
2103  Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc);
2104  break;
2105  case OMPD_flush:
2106  assert(AStmt == nullptr &&
2107  "No associated statement allowed for 'omp flush' directive");
2108  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
2109  break;
2110  case OMPD_ordered:
2111  assert(ClausesWithImplicit.empty() &&
2112  "No clauses are allowed for 'omp ordered' directive");
2113  Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc);
2114  break;
2115  case OMPD_atomic:
2116  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
2117  EndLoc);
2118  break;
2119  case OMPD_teams:
2120  Res =
2121  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2122  break;
2123  case OMPD_target:
2124  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
2125  EndLoc);
2126  break;
2127  case OMPD_cancellation_point:
2128  assert(ClausesWithImplicit.empty() &&
2129  "No clauses are allowed for 'omp cancellation point' directive");
2130  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
2131  "cancellation point' directive");
2132  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
2133  break;
2134  case OMPD_cancel:
2135  assert(ClausesWithImplicit.empty() &&
2136  "No clauses are allowed for 'omp cancel' directive");
2137  assert(AStmt == nullptr &&
2138  "No associated statement allowed for 'omp cancel' directive");
2139  Res = ActOnOpenMPCancelDirective(StartLoc, EndLoc, CancelRegion);
2140  break;
2141  case OMPD_threadprivate:
2142  llvm_unreachable("OpenMP Directive is not allowed");
2143  case OMPD_unknown:
2144  llvm_unreachable("Unknown OpenMP directive");
2145  }
2146 
2147  for (auto P : VarsWithInheritedDSA) {
2148  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
2149  << P.first << P.second->getSourceRange();
2150  }
2151  if (!VarsWithInheritedDSA.empty())
2152  return StmtError();
2153 
2154  if (ErrorFound)
2155  return StmtError();
2156  return Res;
2157 }
2158 
2160  Stmt *AStmt,
2161  SourceLocation StartLoc,
2162  SourceLocation EndLoc) {
2163  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
2164  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
2165  // 1.2.2 OpenMP Language Terminology
2166  // Structured block - An executable statement with a single entry at the
2167  // top and a single exit at the bottom.
2168  // The point of exit cannot be a branch out of the structured block.
2169  // longjmp() and throw() must not violate the entry/exit criteria.
2170  CS->getCapturedDecl()->setNothrow();
2171 
2173 
2174  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
2175  AStmt);
2176 }
2177 
2178 namespace {
2179 /// \brief Helper class for checking canonical form of the OpenMP loops and
2180 /// extracting iteration space of each loop in the loop nest, that will be used
2181 /// for IR generation.
2182 class OpenMPIterationSpaceChecker {
2183  /// \brief Reference to Sema.
2184  Sema &SemaRef;
2185  /// \brief A location for diagnostics (when there is no some better location).
2186  SourceLocation DefaultLoc;
2187  /// \brief A location for diagnostics (when increment is not compatible).
2188  SourceLocation ConditionLoc;
2189  /// \brief A source location for referring to loop init later.
2190  SourceRange InitSrcRange;
2191  /// \brief A source location for referring to condition later.
2192  SourceRange ConditionSrcRange;
2193  /// \brief A source location for referring to increment later.
2194  SourceRange IncrementSrcRange;
2195  /// \brief Loop variable.
2196  VarDecl *Var;
2197  /// \brief Reference to loop variable.
2198  DeclRefExpr *VarRef;
2199  /// \brief Lower bound (initializer for the var).
2200  Expr *LB;
2201  /// \brief Upper bound.
2202  Expr *UB;
2203  /// \brief Loop step (increment).
2204  Expr *Step;
2205  /// \brief This flag is true when condition is one of:
2206  /// Var < UB
2207  /// Var <= UB
2208  /// UB > Var
2209  /// UB >= Var
2210  bool TestIsLessOp;
2211  /// \brief This flag is true when condition is strict ( < or > ).
2212  bool TestIsStrictOp;
2213  /// \brief This flag is true when step is subtracted on each iteration.
2214  bool SubtractStep;
2215 
2216 public:
2217  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
2218  : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc),
2219  InitSrcRange(SourceRange()), ConditionSrcRange(SourceRange()),
2220  IncrementSrcRange(SourceRange()), Var(nullptr), VarRef(nullptr),
2221  LB(nullptr), UB(nullptr), Step(nullptr), TestIsLessOp(false),
2222  TestIsStrictOp(false), SubtractStep(false) {}
2223  /// \brief Check init-expr for canonical loop form and save loop counter
2224  /// variable - #Var and its initialization value - #LB.
2225  bool CheckInit(Stmt *S, bool EmitDiags = true);
2226  /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
2227  /// for less/greater and for strict/non-strict comparison.
2228  bool CheckCond(Expr *S);
2229  /// \brief Check incr-expr for canonical loop form and return true if it
2230  /// does not conform, otherwise save loop step (#Step).
2231  bool CheckInc(Expr *S);
2232  /// \brief Return the loop counter variable.
2233  VarDecl *GetLoopVar() const { return Var; }
2234  /// \brief Return the reference expression to loop counter variable.
2235  DeclRefExpr *GetLoopVarRefExpr() const { return VarRef; }
2236  /// \brief Source range of the loop init.
2237  SourceRange GetInitSrcRange() const { return InitSrcRange; }
2238  /// \brief Source range of the loop condition.
2239  SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
2240  /// \brief Source range of the loop increment.
2241  SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
2242  /// \brief True if the step should be subtracted.
2243  bool ShouldSubtractStep() const { return SubtractStep; }
2244  /// \brief Build the expression to calculate the number of iterations.
2245  Expr *BuildNumIterations(Scope *S, const bool LimitedType) const;
2246  /// \brief Build the precondition expression for the loops.
2247  Expr *BuildPreCond(Scope *S, Expr *Cond) const;
2248  /// \brief Build reference expression to the counter be used for codegen.
2249  Expr *BuildCounterVar() const;
2250  /// \brief Build initization of the counter be used for codegen.
2251  Expr *BuildCounterInit() const;
2252  /// \brief Build step of the counter be used for codegen.
2253  Expr *BuildCounterStep() const;
2254  /// \brief Return true if any expression is dependent.
2255  bool Dependent() const;
2256 
2257 private:
2258  /// \brief Check the right-hand side of an assignment in the increment
2259  /// expression.
2260  bool CheckIncRHS(Expr *RHS);
2261  /// \brief Helper to set loop counter variable and its initializer.
2262  bool SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB);
2263  /// \brief Helper to set upper bound.
2264  bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, const SourceRange &SR,
2265  const SourceLocation &SL);
2266  /// \brief Helper to set loop increment.
2267  bool SetStep(Expr *NewStep, bool Subtract);
2268 };
2269 
2270 bool OpenMPIterationSpaceChecker::Dependent() const {
2271  if (!Var) {
2272  assert(!LB && !UB && !Step);
2273  return false;
2274  }
2275  return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) ||
2276  (UB && UB->isValueDependent()) || (Step && Step->isValueDependent());
2277 }
2278 
2279 template <typename T>
2280 static T *getExprAsWritten(T *E) {
2281  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
2282  E = ExprTemp->getSubExpr();
2283 
2284  if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
2285  E = MTE->GetTemporaryExpr();
2286 
2287  while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
2288  E = Binder->getSubExpr();
2289 
2290  if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
2291  E = ICE->getSubExprAsWritten();
2292  return E->IgnoreParens();
2293 }
2294 
2295 bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar,
2296  DeclRefExpr *NewVarRefExpr,
2297  Expr *NewLB) {
2298  // State consistency checking to ensure correct usage.
2299  assert(Var == nullptr && LB == nullptr && VarRef == nullptr &&
2300  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
2301  if (!NewVar || !NewLB)
2302  return true;
2303  Var = NewVar;
2304  VarRef = NewVarRefExpr;
2305  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
2306  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
2307  if ((Ctor->isCopyOrMoveConstructor() ||
2308  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
2309  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
2310  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
2311  LB = NewLB;
2312  return false;
2313 }
2314 
2315 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
2316  const SourceRange &SR,
2317  const SourceLocation &SL) {
2318  // State consistency checking to ensure correct usage.
2319  assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr &&
2320  !TestIsLessOp && !TestIsStrictOp);
2321  if (!NewUB)
2322  return true;
2323  UB = NewUB;
2324  TestIsLessOp = LessOp;
2325  TestIsStrictOp = StrictOp;
2326  ConditionSrcRange = SR;
2327  ConditionLoc = SL;
2328  return false;
2329 }
2330 
2331 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
2332  // State consistency checking to ensure correct usage.
2333  assert(Var != nullptr && LB != nullptr && Step == nullptr);
2334  if (!NewStep)
2335  return true;
2336  if (!NewStep->isValueDependent()) {
2337  // Check that the step is integer expression.
2338  SourceLocation StepLoc = NewStep->getLocStart();
2339  ExprResult Val =
2340  SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
2341  if (Val.isInvalid())
2342  return true;
2343  NewStep = Val.get();
2344 
2345  // OpenMP [2.6, Canonical Loop Form, Restrictions]
2346  // If test-expr is of form var relational-op b and relational-op is < or
2347  // <= then incr-expr must cause var to increase on each iteration of the
2348  // loop. If test-expr is of form var relational-op b and relational-op is
2349  // > or >= then incr-expr must cause var to decrease on each iteration of
2350  // the loop.
2351  // If test-expr is of form b relational-op var and relational-op is < or
2352  // <= then incr-expr must cause var to decrease on each iteration of the
2353  // loop. If test-expr is of form b relational-op var and relational-op is
2354  // > or >= then incr-expr must cause var to increase on each iteration of
2355  // the loop.
2356  llvm::APSInt Result;
2357  bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
2358  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
2359  bool IsConstNeg =
2360  IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
2361  bool IsConstPos =
2362  IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
2363  bool IsConstZero = IsConstant && !Result.getBoolValue();
2364  if (UB && (IsConstZero ||
2365  (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
2366  : (IsConstPos || (IsUnsigned && !Subtract))))) {
2367  SemaRef.Diag(NewStep->getExprLoc(),
2368  diag::err_omp_loop_incr_not_compatible)
2369  << Var << TestIsLessOp << NewStep->getSourceRange();
2370  SemaRef.Diag(ConditionLoc,
2371  diag::note_omp_loop_cond_requres_compatible_incr)
2372  << TestIsLessOp << ConditionSrcRange;
2373  return true;
2374  }
2375  if (TestIsLessOp == Subtract) {
2376  NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus,
2377  NewStep).get();
2378  Subtract = !Subtract;
2379  }
2380  }
2381 
2382  Step = NewStep;
2383  SubtractStep = Subtract;
2384  return false;
2385 }
2386 
2387 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
2388  // Check init-expr for canonical loop form and save loop counter
2389  // variable - #Var and its initialization value - #LB.
2390  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
2391  // var = lb
2392  // integer-type var = lb
2393  // random-access-iterator-type var = lb
2394  // pointer-type var = lb
2395  //
2396  if (!S) {
2397  if (EmitDiags) {
2398  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
2399  }
2400  return true;
2401  }
2402  InitSrcRange = S->getSourceRange();
2403  if (Expr *E = dyn_cast<Expr>(S))
2404  S = E->IgnoreParens();
2405  if (auto BO = dyn_cast<BinaryOperator>(S)) {
2406  if (BO->getOpcode() == BO_Assign)
2407  if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens()))
2408  return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
2409  BO->getRHS());
2410  } else if (auto DS = dyn_cast<DeclStmt>(S)) {
2411  if (DS->isSingleDecl()) {
2412  if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
2413  if (Var->hasInit()) {
2414  // Accept non-canonical init form here but emit ext. warning.
2415  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
2416  SemaRef.Diag(S->getLocStart(),
2417  diag::ext_omp_loop_not_canonical_init)
2418  << S->getSourceRange();
2419  return SetVarAndLB(Var, nullptr, Var->getInit());
2420  }
2421  }
2422  }
2423  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S))
2424  if (CE->getOperator() == OO_Equal)
2425  if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0)))
2426  return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
2427  CE->getArg(1));
2428 
2429  if (EmitDiags) {
2430  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
2431  << S->getSourceRange();
2432  }
2433  return true;
2434 }
2435 
2436 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
2437 /// variable (which may be the loop variable) if possible.
2438 static const VarDecl *GetInitVarDecl(const Expr *E) {
2439  if (!E)
2440  return nullptr;
2441  E = getExprAsWritten(E);
2442  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
2443  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
2444  if ((Ctor->isCopyOrMoveConstructor() ||
2445  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
2446  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
2447  E = CE->getArg(0)->IgnoreParenImpCasts();
2448  auto DRE = dyn_cast_or_null<DeclRefExpr>(E);
2449  if (!DRE)
2450  return nullptr;
2451  return dyn_cast<VarDecl>(DRE->getDecl());
2452 }
2453 
2454 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
2455  // Check test-expr for canonical form, save upper-bound UB, flags for
2456  // less/greater and for strict/non-strict comparison.
2457  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
2458  // var relational-op b
2459  // b relational-op var
2460  //
2461  if (!S) {
2462  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var;
2463  return true;
2464  }
2465  S = getExprAsWritten(S);
2466  SourceLocation CondLoc = S->getLocStart();
2467  if (auto BO = dyn_cast<BinaryOperator>(S)) {
2468  if (BO->isRelationalOp()) {
2469  if (GetInitVarDecl(BO->getLHS()) == Var)
2470  return SetUB(BO->getRHS(),
2471  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
2472  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
2473  BO->getSourceRange(), BO->getOperatorLoc());
2474  if (GetInitVarDecl(BO->getRHS()) == Var)
2475  return SetUB(BO->getLHS(),
2476  (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
2477  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
2478  BO->getSourceRange(), BO->getOperatorLoc());
2479  }
2480  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
2481  if (CE->getNumArgs() == 2) {
2482  auto Op = CE->getOperator();
2483  switch (Op) {
2484  case OO_Greater:
2485  case OO_GreaterEqual:
2486  case OO_Less:
2487  case OO_LessEqual:
2488  if (GetInitVarDecl(CE->getArg(0)) == Var)
2489  return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
2490  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
2491  CE->getOperatorLoc());
2492  if (GetInitVarDecl(CE->getArg(1)) == Var)
2493  return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
2494  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
2495  CE->getOperatorLoc());
2496  break;
2497  default:
2498  break;
2499  }
2500  }
2501  }
2502  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
2503  << S->getSourceRange() << Var;
2504  return true;
2505 }
2506 
2507 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
2508  // RHS of canonical loop form increment can be:
2509  // var + incr
2510  // incr + var
2511  // var - incr
2512  //
2513  RHS = RHS->IgnoreParenImpCasts();
2514  if (auto BO = dyn_cast<BinaryOperator>(RHS)) {
2515  if (BO->isAdditiveOp()) {
2516  bool IsAdd = BO->getOpcode() == BO_Add;
2517  if (GetInitVarDecl(BO->getLHS()) == Var)
2518  return SetStep(BO->getRHS(), !IsAdd);
2519  if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var)
2520  return SetStep(BO->getLHS(), false);
2521  }
2522  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
2523  bool IsAdd = CE->getOperator() == OO_Plus;
2524  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
2525  if (GetInitVarDecl(CE->getArg(0)) == Var)
2526  return SetStep(CE->getArg(1), !IsAdd);
2527  if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var)
2528  return SetStep(CE->getArg(0), false);
2529  }
2530  }
2531  SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
2532  << RHS->getSourceRange() << Var;
2533  return true;
2534 }
2535 
2536 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
2537  // Check incr-expr for canonical loop form and return true if it
2538  // does not conform.
2539  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
2540  // ++var
2541  // var++
2542  // --var
2543  // var--
2544  // var += incr
2545  // var -= incr
2546  // var = var + incr
2547  // var = incr + var
2548  // var = var - incr
2549  //
2550  if (!S) {
2551  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var;
2552  return true;
2553  }
2554  IncrementSrcRange = S->getSourceRange();
2555  S = S->IgnoreParens();
2556  if (auto UO = dyn_cast<UnaryOperator>(S)) {
2557  if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var)
2558  return SetStep(
2559  SemaRef.ActOnIntegerConstant(UO->getLocStart(),
2560  (UO->isDecrementOp() ? -1 : 1)).get(),
2561  false);
2562  } else if (auto BO = dyn_cast<BinaryOperator>(S)) {
2563  switch (BO->getOpcode()) {
2564  case BO_AddAssign:
2565  case BO_SubAssign:
2566  if (GetInitVarDecl(BO->getLHS()) == Var)
2567  return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
2568  break;
2569  case BO_Assign:
2570  if (GetInitVarDecl(BO->getLHS()) == Var)
2571  return CheckIncRHS(BO->getRHS());
2572  break;
2573  default:
2574  break;
2575  }
2576  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
2577  switch (CE->getOperator()) {
2578  case OO_PlusPlus:
2579  case OO_MinusMinus:
2580  if (GetInitVarDecl(CE->getArg(0)) == Var)
2581  return SetStep(
2582  SemaRef.ActOnIntegerConstant(
2583  CE->getLocStart(),
2584  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(),
2585  false);
2586  break;
2587  case OO_PlusEqual:
2588  case OO_MinusEqual:
2589  if (GetInitVarDecl(CE->getArg(0)) == Var)
2590  return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
2591  break;
2592  case OO_Equal:
2593  if (GetInitVarDecl(CE->getArg(0)) == Var)
2594  return CheckIncRHS(CE->getArg(1));
2595  break;
2596  default:
2597  break;
2598  }
2599  }
2600  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
2601  << S->getSourceRange() << Var;
2602  return true;
2603 }
2604 
2605 namespace {
2606 // Transform variables declared in GNU statement expressions to new ones to
2607 // avoid crash on codegen.
2608 class TransformToNewDefs : public TreeTransform<TransformToNewDefs> {
2609  typedef TreeTransform<TransformToNewDefs> BaseTransform;
2610 
2611 public:
2612  TransformToNewDefs(Sema &SemaRef) : BaseTransform(SemaRef) {}
2613 
2614  Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
2615  if (auto *VD = cast<VarDecl>(D))
2616  if (!isa<ParmVarDecl>(D) && !isa<VarTemplateSpecializationDecl>(D) &&
2617  !isa<ImplicitParamDecl>(D)) {
2618  auto *NewVD = VarDecl::Create(
2619  SemaRef.Context, VD->getDeclContext(), VD->getLocStart(),
2620  VD->getLocation(), VD->getIdentifier(), VD->getType(),
2621  VD->getTypeSourceInfo(), VD->getStorageClass());
2622  NewVD->setTSCSpec(VD->getTSCSpec());
2623  NewVD->setInit(VD->getInit());
2624  NewVD->setInitStyle(VD->getInitStyle());
2625  NewVD->setExceptionVariable(VD->isExceptionVariable());
2626  NewVD->setNRVOVariable(VD->isNRVOVariable());
2627  NewVD->setCXXForRangeDecl(VD->isInExternCXXContext());
2628  NewVD->setConstexpr(VD->isConstexpr());
2629  NewVD->setInitCapture(VD->isInitCapture());
2630  NewVD->setPreviousDeclInSameBlockScope(
2631  VD->isPreviousDeclInSameBlockScope());
2632  VD->getDeclContext()->addHiddenDecl(NewVD);
2633  transformedLocalDecl(VD, NewVD);
2634  return NewVD;
2635  }
2636  return BaseTransform::TransformDefinition(Loc, D);
2637  }
2638 
2639  ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
2640  if (auto *NewD = TransformDecl(E->getExprLoc(), E->getDecl()))
2641  if (E->getDecl() != NewD) {
2642  NewD->setReferenced();
2643  NewD->markUsed(SemaRef.Context);
2644  return DeclRefExpr::Create(
2645  SemaRef.Context, E->getQualifierLoc(), E->getTemplateKeywordLoc(),
2646  cast<ValueDecl>(NewD), E->refersToEnclosingVariableOrCapture(),
2647  E->getNameInfo(), E->getType(), E->getValueKind());
2648  }
2649  return BaseTransform::TransformDeclRefExpr(E);
2650  }
2651 };
2652 }
2653 
2654 /// \brief Build the expression to calculate the number of iterations.
2655 Expr *
2656 OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
2657  const bool LimitedType) const {
2658  TransformToNewDefs Transform(SemaRef);
2659  ExprResult Diff;
2660  auto VarType = Var->getType().getNonReferenceType();
2661  if (VarType->isIntegerType() || VarType->isPointerType() ||
2662  SemaRef.getLangOpts().CPlusPlus) {
2663  // Upper - Lower
2664  auto *UBExpr = TestIsLessOp ? UB : LB;
2665  auto *LBExpr = TestIsLessOp ? LB : UB;
2666  Expr *Upper = Transform.TransformExpr(UBExpr).get();
2667  Expr *Lower = Transform.TransformExpr(LBExpr).get();
2668  if (!Upper || !Lower)
2669  return nullptr;
2670  Upper = SemaRef.PerformImplicitConversion(Upper, UBExpr->getType(),
2672  /*AllowExplicit=*/true)
2673  .get();
2674  Lower = SemaRef.PerformImplicitConversion(Lower, LBExpr->getType(),
2676  /*AllowExplicit=*/true)
2677  .get();
2678  if (!Upper || !Lower)
2679  return nullptr;
2680 
2681  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
2682 
2683  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
2684  // BuildBinOp already emitted error, this one is to point user to upper
2685  // and lower bound, and to tell what is passed to 'operator-'.
2686  SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
2687  << Upper->getSourceRange() << Lower->getSourceRange();
2688  return nullptr;
2689  }
2690  }
2691 
2692  if (!Diff.isUsable())
2693  return nullptr;
2694 
2695  // Upper - Lower [- 1]
2696  if (TestIsStrictOp)
2697  Diff = SemaRef.BuildBinOp(
2698  S, DefaultLoc, BO_Sub, Diff.get(),
2699  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
2700  if (!Diff.isUsable())
2701  return nullptr;
2702 
2703  // Upper - Lower [- 1] + Step
2704  auto NewStep = Transform.TransformExpr(Step->IgnoreImplicit());
2705  if (NewStep.isInvalid())
2706  return nullptr;
2707  NewStep = SemaRef.PerformImplicitConversion(
2708  NewStep.get(), Step->IgnoreImplicit()->getType(), Sema::AA_Converting,
2709  /*AllowExplicit=*/true);
2710  if (NewStep.isInvalid())
2711  return nullptr;
2712  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
2713  if (!Diff.isUsable())
2714  return nullptr;
2715 
2716  // Parentheses (for dumping/debugging purposes only).
2717  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
2718  if (!Diff.isUsable())
2719  return nullptr;
2720 
2721  // (Upper - Lower [- 1] + Step) / Step
2722  NewStep = Transform.TransformExpr(Step->IgnoreImplicit());
2723  if (NewStep.isInvalid())
2724  return nullptr;
2725  NewStep = SemaRef.PerformImplicitConversion(
2726  NewStep.get(), Step->IgnoreImplicit()->getType(), Sema::AA_Converting,
2727  /*AllowExplicit=*/true);
2728  if (NewStep.isInvalid())
2729  return nullptr;
2730  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
2731  if (!Diff.isUsable())
2732  return nullptr;
2733 
2734  // OpenMP runtime requires 32-bit or 64-bit loop variables.
2735  QualType Type = Diff.get()->getType();
2736  auto &C = SemaRef.Context;
2737  bool UseVarType = VarType->hasIntegerRepresentation() &&
2738  C.getTypeSize(Type) > C.getTypeSize(VarType);
2739  if (!Type->isIntegerType() || UseVarType) {
2740  unsigned NewSize =
2741  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
2742  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
2744  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
2745  Diff = SemaRef.PerformImplicitConversion(
2746  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
2747  if (!Diff.isUsable())
2748  return nullptr;
2749  }
2750  if (LimitedType) {
2751  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
2752  if (NewSize != C.getTypeSize(Type)) {
2753  if (NewSize < C.getTypeSize(Type)) {
2754  assert(NewSize == 64 && "incorrect loop var size");
2755  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
2756  << InitSrcRange << ConditionSrcRange;
2757  }
2758  QualType NewType = C.getIntTypeForBitwidth(
2759  NewSize, Type->hasSignedIntegerRepresentation() ||
2760  C.getTypeSize(Type) < NewSize);
2761  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
2762  Sema::AA_Converting, true);
2763  if (!Diff.isUsable())
2764  return nullptr;
2765  }
2766  }
2767 
2768  return Diff.get();
2769 }
2770 
2771 Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const {
2772  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
2773  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
2774  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
2775  TransformToNewDefs Transform(SemaRef);
2776 
2777  auto NewLB = Transform.TransformExpr(LB);
2778  auto NewUB = Transform.TransformExpr(UB);
2779  if (NewLB.isInvalid() || NewUB.isInvalid())
2780  return Cond;
2781  NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->getType(),
2783  /*AllowExplicit=*/true);
2784  NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->getType(),
2786  /*AllowExplicit=*/true);
2787  if (NewLB.isInvalid() || NewUB.isInvalid())
2788  return Cond;
2789  auto CondExpr = SemaRef.BuildBinOp(
2790  S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
2791  : (TestIsStrictOp ? BO_GT : BO_GE),
2792  NewLB.get(), NewUB.get());
2793  if (CondExpr.isUsable()) {
2794  CondExpr = SemaRef.PerformImplicitConversion(
2795  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
2796  /*AllowExplicit=*/true);
2797  }
2798  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
2799  // Otherwise use original loop conditon and evaluate it in runtime.
2800  return CondExpr.isUsable() ? CondExpr.get() : Cond;
2801 }
2802 
2803 /// \brief Build reference expression to the counter be used for codegen.
2804 Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const {
2805  return buildDeclRefExpr(SemaRef, Var, Var->getType(), DefaultLoc);
2806 }
2807 
2808 /// \brief Build initization of the counter be used for codegen.
2810 
2811 /// \brief Build step of the counter be used for codegen.
2812 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
2813 
2814 /// \brief Iteration space of a single for loop.
2815 struct LoopIterationSpace {
2816  /// \brief Condition of the loop.
2817  Expr *PreCond;
2818  /// \brief This expression calculates the number of iterations in the loop.
2819  /// It is always possible to calculate it before starting the loop.
2820  Expr *NumIterations;
2821  /// \brief The loop counter variable.
2822  Expr *CounterVar;
2823  /// \brief This is initializer for the initial value of #CounterVar.
2824  Expr *CounterInit;
2825  /// \brief This is step for the #CounterVar used to generate its update:
2826  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
2827  Expr *CounterStep;
2828  /// \brief Should step be subtracted?
2829  bool Subtract;
2830  /// \brief Source range of the loop init.
2831  SourceRange InitSrcRange;
2832  /// \brief Source range of the loop condition.
2833  SourceRange CondSrcRange;
2834  /// \brief Source range of the loop increment.
2835  SourceRange IncSrcRange;
2836 };
2837 
2838 } // namespace
2839 
2841  assert(getLangOpts().OpenMP && "OpenMP is not active.");
2842  assert(Init && "Expected loop in canonical form.");
2843  unsigned CollapseIteration = DSAStack->getCollapseNumber();
2844  if (CollapseIteration > 0 &&
2845  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2846  OpenMPIterationSpaceChecker ISC(*this, ForLoc);
2847  if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) {
2848  DSAStack->addLoopControlVariable(ISC.GetLoopVar());
2849  }
2850  DSAStack->setCollapseNumber(CollapseIteration - 1);
2851  }
2852 }
2853 
2854 /// \brief Called on a for stmt to check and extract its iteration space
2855 /// for further processing (such as collapsing).
2857  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
2858  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
2859  Expr *NestedLoopCountExpr,
2860  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
2861  LoopIterationSpace &ResultIterSpace) {
2862  // OpenMP [2.6, Canonical Loop Form]
2863  // for (init-expr; test-expr; incr-expr) structured-block
2864  auto For = dyn_cast_or_null<ForStmt>(S);
2865  if (!For) {
2866  SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
2867  << (NestedLoopCountExpr != nullptr) << getOpenMPDirectiveName(DKind)
2868  << NestedLoopCount << (CurrentNestedLoopCount > 0)
2869  << CurrentNestedLoopCount;
2870  if (NestedLoopCount > 1)
2871  SemaRef.Diag(NestedLoopCountExpr->getExprLoc(),
2872  diag::note_omp_collapse_expr)
2873  << NestedLoopCountExpr->getSourceRange();
2874  return true;
2875  }
2876  assert(For->getBody());
2877 
2878  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
2879 
2880  // Check init.
2881  auto Init = For->getInit();
2882  if (ISC.CheckInit(Init)) {
2883  return true;
2884  }
2885 
2886  bool HasErrors = false;
2887 
2888  // Check loop variable's type.
2889  auto Var = ISC.GetLoopVar();
2890 
2891  // OpenMP [2.6, Canonical Loop Form]
2892  // Var is one of the following:
2893  // A variable of signed or unsigned integer type.
2894  // For C++, a variable of a random access iterator type.
2895  // For C, a variable of a pointer type.
2896  auto VarType = Var->getType();
2897  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
2898  !VarType->isPointerType() &&
2899  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
2900  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
2901  << SemaRef.getLangOpts().CPlusPlus;
2902  HasErrors = true;
2903  }
2904 
2905  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a
2906  // Construct
2907  // The loop iteration variable(s) in the associated for-loop(s) of a for or
2908  // parallel for construct is (are) private.
2909  // The loop iteration variable in the associated for-loop of a simd construct
2910  // with just one associated for-loop is linear with a constant-linear-step
2911  // that is the increment of the associated for-loop.
2912  // Exclude loop var from the list of variables with implicitly defined data
2913  // sharing attributes.
2914  VarsWithImplicitDSA.erase(Var);
2915 
2916  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in
2917  // a Construct, C/C++].
2918  // The loop iteration variable in the associated for-loop of a simd construct
2919  // with just one associated for-loop may be listed in a linear clause with a
2920  // constant-linear-step that is the increment of the associated for-loop.
2921  // The loop iteration variable(s) in the associated for-loop(s) of a for or
2922  // parallel for construct may be listed in a private or lastprivate clause.
2923  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false);
2924  auto LoopVarRefExpr = ISC.GetLoopVarRefExpr();
2925  // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
2926  // declared in the loop and it is predetermined as a private.
2927  auto PredeterminedCKind =
2928  isOpenMPSimdDirective(DKind)
2929  ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
2930  : OMPC_private;
2931  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
2932  DVar.CKind != OMPC_threadprivate && DVar.CKind != PredeterminedCKind) ||
2934  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private &&
2935  DVar.CKind != OMPC_lastprivate && DVar.CKind != OMPC_threadprivate)) &&
2936  ((DVar.CKind != OMPC_private && DVar.CKind != OMPC_threadprivate) ||
2937  DVar.RefExpr != nullptr)) {
2938  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
2939  << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
2940  << getOpenMPClauseName(PredeterminedCKind);
2941  if (DVar.RefExpr == nullptr)
2942  DVar.CKind = PredeterminedCKind;
2943  ReportOriginalDSA(SemaRef, &DSA, Var, DVar, /*IsLoopIterVar=*/true);
2944  HasErrors = true;
2945  } else if (LoopVarRefExpr != nullptr) {
2946  // Make the loop iteration variable private (for worksharing constructs),
2947  // linear (for simd directives with the only one associated loop) or
2948  // lastprivate (for simd directives with several collapsed loops).
2949  if (DVar.CKind == OMPC_unknown)
2950  DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(),
2951  /*FromParent=*/false);
2952  DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind);
2953  }
2954 
2955  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
2956 
2957  // Check test-expr.
2958  HasErrors |= ISC.CheckCond(For->getCond());
2959 
2960  // Check incr-expr.
2961  HasErrors |= ISC.CheckInc(For->getInc());
2962 
2963  if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
2964  return HasErrors;
2965 
2966  // Build the loop's iteration space representation.
2967  ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond());
2968  ResultIterSpace.NumIterations = ISC.BuildNumIterations(
2969  DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind));
2970  ResultIterSpace.CounterVar = ISC.BuildCounterVar();
2971  ResultIterSpace.CounterInit = ISC.BuildCounterInit();
2972  ResultIterSpace.CounterStep = ISC.BuildCounterStep();
2973  ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
2974  ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
2975  ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
2976  ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
2977 
2978  HasErrors |= (ResultIterSpace.PreCond == nullptr ||
2979  ResultIterSpace.NumIterations == nullptr ||
2980  ResultIterSpace.CounterVar == nullptr ||
2981  ResultIterSpace.CounterInit == nullptr ||
2982  ResultIterSpace.CounterStep == nullptr);
2983 
2984  return HasErrors;
2985 }
2986 
2987 /// \brief Build 'VarRef = Start.
2989  ExprResult VarRef, ExprResult Start) {
2990  TransformToNewDefs Transform(SemaRef);
2991  // Build 'VarRef = Start.
2992  auto NewStart = Transform.TransformExpr(Start.get()->IgnoreImplicit());
2993  if (NewStart.isInvalid())
2994  return ExprError();
2995  NewStart = SemaRef.PerformImplicitConversion(
2996  NewStart.get(), Start.get()->IgnoreImplicit()->getType(),
2998  /*AllowExplicit=*/true);
2999  if (NewStart.isInvalid())
3000  return ExprError();
3001  NewStart = SemaRef.PerformImplicitConversion(
3002  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
3003  /*AllowExplicit=*/true);
3004  if (!NewStart.isUsable())
3005  return ExprError();
3006 
3007  auto Init =
3008  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
3009  return Init;
3010 }
3011 
3012 /// \brief Build 'VarRef = Start + Iter * Step'.
3014  SourceLocation Loc, ExprResult VarRef,
3015  ExprResult Start, ExprResult Iter,
3016  ExprResult Step, bool Subtract) {
3017  // Add parentheses (for debugging purposes only).
3018  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
3019  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
3020  !Step.isUsable())
3021  return ExprError();
3022 
3023  TransformToNewDefs Transform(SemaRef);
3024  auto NewStep = Transform.TransformExpr(Step.get()->IgnoreImplicit());
3025  if (NewStep.isInvalid())
3026  return ExprError();
3027  NewStep = SemaRef.PerformImplicitConversion(
3028  NewStep.get(), Step.get()->IgnoreImplicit()->getType(),
3030  /*AllowExplicit=*/true);
3031  if (NewStep.isInvalid())
3032  return ExprError();
3033  ExprResult Update =
3034  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
3035  if (!Update.isUsable())
3036  return ExprError();
3037 
3038  // Build 'VarRef = Start + Iter * Step'.
3039  auto NewStart = Transform.TransformExpr(Start.get()->IgnoreImplicit());
3040  if (NewStart.isInvalid())
3041  return ExprError();
3042  NewStart = SemaRef.PerformImplicitConversion(
3043  NewStart.get(), Start.get()->IgnoreImplicit()->getType(),
3045  /*AllowExplicit=*/true);
3046  if (NewStart.isInvalid())
3047  return ExprError();
3048  Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add),
3049  NewStart.get(), Update.get());
3050  if (!Update.isUsable())
3051  return ExprError();
3052 
3053  Update = SemaRef.PerformImplicitConversion(
3054  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
3055  if (!Update.isUsable())
3056  return ExprError();
3057 
3058  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
3059  return Update;
3060 }
3061 
3062 /// \brief Convert integer expression \a E to make it have at least \a Bits
3063 /// bits.
3064 static ExprResult WidenIterationCount(unsigned Bits, Expr *E,
3065  Sema &SemaRef) {
3066  if (E == nullptr)
3067  return ExprError();
3068  auto &C = SemaRef.Context;
3069  QualType OldType = E->getType();
3070  unsigned HasBits = C.getTypeSize(OldType);
3071  if (HasBits >= Bits)
3072  return ExprResult(E);
3073  // OK to convert to signed, because new type has more bits than old.
3074  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
3075  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
3076  true);
3077 }
3078 
3079 /// \brief Check if the given expression \a E is a constant integer that fits
3080 /// into \a Bits bits.
3081 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
3082  if (E == nullptr)
3083  return false;
3084  llvm::APSInt Result;
3085  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
3086  return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
3087  return false;
3088 }
3089 
3090 /// \brief Called on a for stmt to check itself and nested loops (if any).
3091 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
3092 /// number of collapsed loops otherwise.
3093 static unsigned
3094 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
3095  Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA,
3096  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
3098  unsigned NestedLoopCount = 1;
3099  if (NestedLoopCountExpr) {
3100  // Found 'collapse' clause - calculate collapse number.
3101  llvm::APSInt Result;
3102  if (NestedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
3103  NestedLoopCount = Result.getLimitedValue();
3104  }
3105  // This is helper routine for loop directives (e.g., 'for', 'simd',
3106  // 'for simd', etc.).
3108  IterSpaces.resize(NestedLoopCount);
3109  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
3110  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
3111  if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
3112  NestedLoopCount, NestedLoopCountExpr,
3113  VarsWithImplicitDSA, IterSpaces[Cnt]))
3114  return 0;
3115  // Move on to the next nested for loop, or to the loop body.
3116  // OpenMP [2.8.1, simd construct, Restrictions]
3117  // All loops associated with the construct must be perfectly nested; that
3118  // is, there must be no intervening code nor any OpenMP directive between
3119  // any two loops.
3120  CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
3121  }
3122 
3123  Built.clear(/* size */ NestedLoopCount);
3124 
3125  if (SemaRef.CurContext->isDependentContext())
3126  return NestedLoopCount;
3127 
3128  // An example of what is generated for the following code:
3129  //
3130  // #pragma omp simd collapse(2)
3131  // for (i = 0; i < NI; ++i)
3132  // for (j = J0; j < NJ; j+=2) {
3133  // <loop body>
3134  // }
3135  //
3136  // We generate the code below.
3137  // Note: the loop body may be outlined in CodeGen.
3138  // Note: some counters may be C++ classes, operator- is used to find number of
3139  // iterations and operator+= to calculate counter value.
3140  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
3141  // or i64 is currently supported).
3142  //
3143  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
3144  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
3145  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
3146  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
3147  // // similar updates for vars in clauses (e.g. 'linear')
3148  // <loop body (using local i and j)>
3149  // }
3150  // i = NI; // assign final values of counters
3151  // j = NJ;
3152  //
3153 
3154  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
3155  // the iteration counts of the collapsed for loops.
3156  // Precondition tests if there is at least one iteration (all conditions are
3157  // true).
3158  auto PreCond = ExprResult(IterSpaces[0].PreCond);
3159  auto N0 = IterSpaces[0].NumIterations;
3160  ExprResult LastIteration32 = WidenIterationCount(
3161  32 /* Bits */, SemaRef.PerformImplicitConversion(
3162  N0->IgnoreImpCasts(), N0->getType(),
3163  Sema::AA_Converting, /*AllowExplicit=*/true)
3164  .get(),
3165  SemaRef);
3166  ExprResult LastIteration64 = WidenIterationCount(
3167  64 /* Bits */, SemaRef.PerformImplicitConversion(
3168  N0->IgnoreImpCasts(), N0->getType(),
3169  Sema::AA_Converting, /*AllowExplicit=*/true)
3170  .get(),
3171  SemaRef);
3172 
3173  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
3174  return NestedLoopCount;
3175 
3176  auto &C = SemaRef.Context;
3177  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
3178 
3179  Scope *CurScope = DSA.getCurScope();
3180  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
3181  if (PreCond.isUsable()) {
3182  PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd,
3183  PreCond.get(), IterSpaces[Cnt].PreCond);
3184  }
3185  auto N = IterSpaces[Cnt].NumIterations;
3186  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
3187  if (LastIteration32.isUsable())
3188  LastIteration32 = SemaRef.BuildBinOp(
3189  CurScope, SourceLocation(), BO_Mul, LastIteration32.get(),
3190  SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
3192  /*AllowExplicit=*/true)
3193  .get());
3194  if (LastIteration64.isUsable())
3195  LastIteration64 = SemaRef.BuildBinOp(
3196  CurScope, SourceLocation(), BO_Mul, LastIteration64.get(),
3197  SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
3199  /*AllowExplicit=*/true)
3200  .get());
3201  }
3202 
3203  // Choose either the 32-bit or 64-bit version.
3204  ExprResult LastIteration = LastIteration64;
3205  if (LastIteration32.isUsable() &&
3206  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
3207  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
3208  FitsInto(
3209  32 /* Bits */,
3210  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
3211  LastIteration64.get(), SemaRef)))
3212  LastIteration = LastIteration32;
3213 
3214  if (!LastIteration.isUsable())
3215  return 0;
3216 
3217  // Save the number of iterations.
3218  ExprResult NumIterations = LastIteration;
3219  {
3220  LastIteration = SemaRef.BuildBinOp(
3221  CurScope, SourceLocation(), BO_Sub, LastIteration.get(),
3222  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3223  if (!LastIteration.isUsable())
3224  return 0;
3225  }
3226 
3227  // Calculate the last iteration number beforehand instead of doing this on
3228  // each iteration. Do not do this if the number of iterations may be kfold-ed.
3229  llvm::APSInt Result;
3230  bool IsConstant =
3231  LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
3232  ExprResult CalcLastIteration;
3233  if (!IsConstant) {
3234  SourceLocation SaveLoc;
3235  VarDecl *SaveVar =
3236  buildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(),
3237  ".omp.last.iteration");
3238  ExprResult SaveRef = buildDeclRefExpr(
3239  SemaRef, SaveVar, LastIteration.get()->getType(), SaveLoc);
3240  CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign,
3241  SaveRef.get(), LastIteration.get());
3242  LastIteration = SaveRef;
3243 
3244  // Prepare SaveRef + 1.
3245  NumIterations = SemaRef.BuildBinOp(
3246  CurScope, SaveLoc, BO_Add, SaveRef.get(),
3247  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3248  if (!NumIterations.isUsable())
3249  return 0;
3250  }
3251 
3252  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
3253 
3254  QualType VType = LastIteration.get()->getType();
3255  // Build variables passed into runtime, nesessary for worksharing directives.
3256  ExprResult LB, UB, IL, ST, EUB;
3257  if (isOpenMPWorksharingDirective(DKind)) {
3258  // Lower bound variable, initialized with zero.
3259  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
3260  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
3261  SemaRef.AddInitializerToDecl(
3262  LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
3263  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
3264 
3265  // Upper bound variable, initialized with last iteration number.
3266  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
3267  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
3268  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
3269  /*DirectInit*/ false,
3270  /*TypeMayContainAuto*/ false);
3271 
3272  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
3273  // This will be used to implement clause 'lastprivate'.
3274  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
3275  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
3276  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
3277  SemaRef.AddInitializerToDecl(
3278  ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
3279  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
3280 
3281  // Stride variable returned by runtime (we initialize it to 1 by default).
3282  VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride");
3283  ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc);
3284  SemaRef.AddInitializerToDecl(
3285  STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
3286  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
3287 
3288  // Build expression: UB = min(UB, LastIteration)
3289  // It is nesessary for CodeGen of directives with static scheduling.
3290  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
3291  UB.get(), LastIteration.get());
3292  ExprResult CondOp = SemaRef.ActOnConditionalOp(
3293  InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
3294  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
3295  CondOp.get());
3296  EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
3297  }
3298 
3299  // Build the iteration variable and its initialization before loop.
3300  ExprResult IV;
3301  ExprResult Init;
3302  {
3303  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv");
3304  IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc);
3305  Expr *RHS = isOpenMPWorksharingDirective(DKind)
3306  ? LB.get()
3307  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
3308  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
3309  Init = SemaRef.ActOnFinishFullExpr(Init.get());
3310  }
3311 
3312  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
3313  SourceLocation CondLoc;
3314  ExprResult Cond =
3316  ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
3317  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
3318  NumIterations.get());
3319 
3320  // Loop increment (IV = IV + 1)
3321  SourceLocation IncLoc;
3322  ExprResult Inc =
3323  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
3324  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
3325  if (!Inc.isUsable())
3326  return 0;
3327  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
3328  Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
3329  if (!Inc.isUsable())
3330  return 0;
3331 
3332  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
3333  // Used for directives with static scheduling.
3334  ExprResult NextLB, NextUB;
3335  if (isOpenMPWorksharingDirective(DKind)) {
3336  // LB + ST
3337  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
3338  if (!NextLB.isUsable())
3339  return 0;
3340  // LB = LB + ST
3341  NextLB =
3342  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
3343  NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
3344  if (!NextLB.isUsable())
3345  return 0;
3346  // UB + ST
3347  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
3348  if (!NextUB.isUsable())
3349  return 0;
3350  // UB = UB + ST
3351  NextUB =
3352  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
3353  NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
3354  if (!NextUB.isUsable())
3355  return 0;
3356  }
3357 
3358  // Build updates and final values of the loop counters.
3359  bool HasErrors = false;
3360  Built.Counters.resize(NestedLoopCount);
3361  Built.Inits.resize(NestedLoopCount);
3362  Built.Updates.resize(NestedLoopCount);
3363  Built.Finals.resize(NestedLoopCount);
3364  {
3365  ExprResult Div;
3366  // Go from inner nested loop to outer.
3367  for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
3368  LoopIterationSpace &IS = IterSpaces[Cnt];
3369  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
3370  // Build: Iter = (IV / Div) % IS.NumIters
3371  // where Div is product of previous iterations' IS.NumIters.
3372  ExprResult Iter;
3373  if (Div.isUsable()) {
3374  Iter =
3375  SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
3376  } else {
3377  Iter = IV;
3378  assert((Cnt == (int)NestedLoopCount - 1) &&
3379  "unusable div expected on first iteration only");
3380  }
3381 
3382  if (Cnt != 0 && Iter.isUsable())
3383  Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
3384  IS.NumIterations);
3385  if (!Iter.isUsable()) {
3386  HasErrors = true;
3387  break;
3388  }
3389 
3390  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
3391  auto *CounterVar = buildDeclRefExpr(
3392  SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()),
3393  IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
3394  /*RefersToCapture=*/true);
3395  ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
3396  IS.CounterInit);
3397  if (!Init.isUsable()) {
3398  HasErrors = true;
3399  break;
3400  }
3401  ExprResult Update =
3402  BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
3403  IS.CounterInit, Iter, IS.CounterStep, IS.Subtract);
3404  if (!Update.isUsable()) {
3405  HasErrors = true;
3406  break;
3407  }
3408 
3409  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
3411  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
3412  IS.NumIterations, IS.CounterStep, IS.Subtract);
3413  if (!Final.isUsable()) {
3414  HasErrors = true;
3415  break;
3416  }
3417 
3418  // Build Div for the next iteration: Div <- Div * IS.NumIters
3419  if (Cnt != 0) {
3420  if (Div.isUnset())
3421  Div = IS.NumIterations;
3422  else
3423  Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
3424  IS.NumIterations);
3425 
3426  // Add parentheses (for debugging purposes only).
3427  if (Div.isUsable())
3428  Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get());
3429  if (!Div.isUsable()) {
3430  HasErrors = true;
3431  break;
3432  }
3433  }
3434  if (!Update.isUsable() || !Final.isUsable()) {
3435  HasErrors = true;
3436  break;
3437  }
3438  // Save results
3439  Built.Counters[Cnt] = IS.CounterVar;
3440  Built.Inits[Cnt] = Init.get();
3441  Built.Updates[Cnt] = Update.get();
3442  Built.Finals[Cnt] = Final.get();
3443  }
3444  }
3445 
3446  if (HasErrors)
3447  return 0;
3448 
3449  // Save results
3450  Built.IterationVarRef = IV.get();
3451  Built.LastIteration = LastIteration.get();
3452  Built.NumIterations = NumIterations.get();
3453  Built.CalcLastIteration =
3454  SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
3455  Built.PreCond = PreCond.get();
3456  Built.Cond = Cond.get();
3457  Built.Init = Init.get();
3458  Built.Inc = Inc.get();
3459  Built.LB = LB.get();
3460  Built.UB = UB.get();
3461  Built.IL = IL.get();
3462  Built.ST = ST.get();
3463  Built.EUB = EUB.get();
3464  Built.NLB = NextLB.get();
3465  Built.NUB = NextUB.get();
3466 
3467  return NestedLoopCount;
3468 }
3469 
3471  auto &&CollapseFilter = [](const OMPClause *C) -> bool {
3472  return C->getClauseKind() == OMPC_collapse;
3473  };
3475  Clauses, std::move(CollapseFilter));
3476  if (I)
3477  return cast<OMPCollapseClause>(*I)->getNumForLoops();
3478  return nullptr;
3479 }
3480 
3482  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
3483  SourceLocation EndLoc,
3484  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3486  // In presence of clause 'collapse', it will define the nested loops number.
3487  unsigned NestedLoopCount =
3488  CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this,
3489  *DSAStack, VarsWithImplicitDSA, B);
3490  if (NestedLoopCount == 0)
3491  return StmtError();
3492 
3493  assert((CurContext->isDependentContext() || B.builtAll()) &&
3494  "omp simd loop exprs were not built");
3495 
3496  if (!CurContext->isDependentContext()) {
3497  // Finalize the clauses that need pre-built expressions for CodeGen.
3498  for (auto C : Clauses) {
3499  if (auto LC = dyn_cast<OMPLinearClause>(C))
3500  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
3501  B.NumIterations, *this, CurScope))
3502  return StmtError();
3503  }
3504  }
3505 
3507  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
3508  Clauses, AStmt, B);
3509 }
3510 
3512  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
3513  SourceLocation EndLoc,
3514  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3516  // In presence of clause 'collapse', it will define the nested loops number.
3517  unsigned NestedLoopCount =
3518  CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this,
3519  *DSAStack, VarsWithImplicitDSA, B);
3520  if (NestedLoopCount == 0)
3521  return StmtError();
3522 
3523  assert((CurContext->isDependentContext() || B.builtAll()) &&
3524  "omp for loop exprs were not built");
3525 
3527  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
3528  Clauses, AStmt, B);
3529 }
3530 
3532  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
3533  SourceLocation EndLoc,
3534  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3536  // In presence of clause 'collapse', it will define the nested loops number.
3537  unsigned NestedLoopCount =
3538  CheckOpenMPLoop(OMPD_for_simd, GetCollapseNumberExpr(Clauses), AStmt,
3539  *this, *DSAStack, VarsWithImplicitDSA, B);
3540  if (NestedLoopCount == 0)
3541  return StmtError();
3542 
3543  assert((CurContext->isDependentContext() || B.builtAll()) &&
3544  "omp for simd loop exprs were not built");
3545 
3546  if (!CurContext->isDependentContext()) {
3547  // Finalize the clauses that need pre-built expressions for CodeGen.
3548  for (auto C : Clauses) {
3549  if (auto LC = dyn_cast<OMPLinearClause>(C))
3550  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
3551  B.NumIterations, *this, CurScope))
3552  return StmtError();
3553  }
3554  }
3555 
3557  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
3558  Clauses, AStmt, B);
3559 }
3560 
3562  Stmt *AStmt,
3563  SourceLocation StartLoc,
3564  SourceLocation EndLoc) {
3565  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3566  auto BaseStmt = AStmt;
3567  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
3568  BaseStmt = CS->getCapturedStmt();
3569  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
3570  auto S = C->children();
3571  if (!S)
3572  return StmtError();
3573  // All associated statements must be '#pragma omp section' except for
3574  // the first one.
3575  for (Stmt *SectionStmt : ++S) {
3576  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
3577  if (SectionStmt)
3578  Diag(SectionStmt->getLocStart(),
3579  diag::err_omp_sections_substmt_not_section);
3580  return StmtError();
3581  }
3582  }
3583  } else {
3584  Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
3585  return StmtError();
3586  }
3587 
3589 
3590  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses,
3591  AStmt);
3592 }
3593 
3595  SourceLocation StartLoc,
3596  SourceLocation EndLoc) {
3597  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3598 
3600 
3601  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt);
3602 }
3603 
3605  Stmt *AStmt,
3606  SourceLocation StartLoc,
3607  SourceLocation EndLoc) {
3608  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3609 
3611 
3612  // OpenMP [2.7.3, single Construct, Restrictions]
3613  // The copyprivate clause must not be used with the nowait clause.
3614  OMPClause *Nowait = nullptr;
3615  OMPClause *Copyprivate = nullptr;
3616  for (auto *Clause : Clauses) {
3617  if (Clause->getClauseKind() == OMPC_nowait)
3618  Nowait = Clause;
3619  else if (Clause->getClauseKind() == OMPC_copyprivate)
3620  Copyprivate = Clause;
3621  if (Copyprivate && Nowait) {
3622  Diag(Copyprivate->getLocStart(),
3623  diag::err_omp_single_copyprivate_with_nowait);
3624  Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
3625  return StmtError();
3626  }
3627  }
3628 
3629  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
3630 }
3631 
3633  SourceLocation StartLoc,
3634  SourceLocation EndLoc) {
3635  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3636 
3638 
3639  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
3640 }
3641 
3642 StmtResult
3644  Stmt *AStmt, SourceLocation StartLoc,
3645  SourceLocation EndLoc) {
3646  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3647 
3649 
3650  return OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
3651  AStmt);
3652 }
3653 
3655  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
3656  SourceLocation EndLoc,
3657  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3658  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3659  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3660  // 1.2.2 OpenMP Language Terminology
3661  // Structured block - An executable statement with a single entry at the
3662  // top and a single exit at the bottom.
3663  // The point of exit cannot be a branch out of the structured block.
3664  // longjmp() and throw() must not violate the entry/exit criteria.
3665  CS->getCapturedDecl()->setNothrow();
3666 
3668  // In presence of clause 'collapse', it will define the nested loops number.
3669  unsigned NestedLoopCount =
3670  CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt,
3671  *this, *DSAStack, VarsWithImplicitDSA, B);
3672  if (NestedLoopCount == 0)
3673  return StmtError();
3674 
3675  assert((CurContext->isDependentContext() || B.builtAll()) &&
3676  "omp parallel for loop exprs were not built");
3677 
3679  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
3680  NestedLoopCount, Clauses, AStmt, B);
3681 }
3682 
3684  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
3685  SourceLocation EndLoc,
3686  llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3687  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3688  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3689  // 1.2.2 OpenMP Language Terminology
3690  // Structured block - An executable statement with a single entry at the
3691  // top and a single exit at the bottom.
3692  // The point of exit cannot be a branch out of the structured block.
3693  // longjmp() and throw() must not violate the entry/exit criteria.
3694  CS->getCapturedDecl()->setNothrow();
3695 
3697  // In presence of clause 'collapse', it will define the nested loops number.
3698  unsigned NestedLoopCount =
3699  CheckOpenMPLoop(OMPD_parallel_for_simd, GetCollapseNumberExpr(Clauses),
3700  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
3701  if (NestedLoopCount == 0)
3702  return StmtError();
3703 
3704  if (!CurContext->isDependentContext()) {
3705  // Finalize the clauses that need pre-built expressions for CodeGen.
3706  for (auto C : Clauses) {
3707  if (auto LC = dyn_cast<OMPLinearClause>(C))
3708  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
3709  B.NumIterations, *this, CurScope))
3710  return StmtError();
3711  }
3712  }
3713 
3716  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
3717 }
3718 
3719 StmtResult
3721  Stmt *AStmt, SourceLocation StartLoc,
3722  SourceLocation EndLoc) {
3723  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3724  auto BaseStmt = AStmt;
3725  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
3726  BaseStmt = CS->getCapturedStmt();
3727  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
3728  auto S = C->children();
3729  if (!S)
3730  return StmtError();
3731  // All associated statements must be '#pragma omp section' except for
3732  // the first one.
3733  for (Stmt *SectionStmt : ++S) {
3734  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
3735  if (SectionStmt)
3736  Diag(SectionStmt->getLocStart(),
3737  diag::err_omp_parallel_sections_substmt_not_section);
3738  return StmtError();
3739  }
3740  }
3741  } else {
3742  Diag(AStmt->getLocStart(),
3743  diag::err_omp_parallel_sections_not_compound_stmt);
3744  return StmtError();
3745  }
3746 
3748 
3749  return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc,
3750  Clauses, AStmt);
3751 }
3752 
3754  Stmt *AStmt, SourceLocation StartLoc,
3755  SourceLocation EndLoc) {
3756  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3757  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3758  // 1.2.2 OpenMP Language Terminology
3759  // Structured block - An executable statement with a single entry at the
3760  // top and a single exit at the bottom.
3761  // The point of exit cannot be a branch out of the structured block.
3762  // longjmp() and throw() must not violate the entry/exit criteria.
3763  CS->getCapturedDecl()->setNothrow();
3764 
3766 
3767  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
3768 }
3769 
3771  SourceLocation EndLoc) {
3772  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
3773 }
3774 
3776  SourceLocation EndLoc) {
3777  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
3778 }
3779 
3781  SourceLocation EndLoc) {
3782  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
3783 }
3784 
3786  SourceLocation StartLoc,
3787  SourceLocation EndLoc) {
3788  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3789 
3791 
3792  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt);
3793 }
3794 
3796  SourceLocation StartLoc,
3797  SourceLocation EndLoc) {
3798  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
3799  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
3800 }
3801 
3803  SourceLocation StartLoc,
3804  SourceLocation EndLoc) {
3805  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
3806 
3808 
3809  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt);
3810 }
3811 
3812 namespace {
3813 /// \brief Helper class for checking expression in 'omp atomic [update]'
3814 /// construct.
3815 class OpenMPAtomicUpdateChecker {
3816  /// \brief Error results for atomic update expressions.
3817  enum ExprAnalysisErrorCode {
3818  /// \brief A statement is not an expression statement.
3819  NotAnExpression,
3820  /// \brief Expression is not builtin binary or unary operation.
3821  NotABinaryOrUnaryExpression,
3822  /// \brief Unary operation is not post-/pre- increment/decrement operation.
3823  NotAnUnaryIncDecExpression,
3824  /// \brief An expression is not of scalar type.
3825  NotAScalarType,
3826  /// \brief A binary operation is not an assignment operation.
3827  NotAnAssignmentOp,
3828  /// \brief RHS part of the binary operation is not a binary expression.
3829  NotABinaryExpression,
3830  /// \brief RHS part is not additive/multiplicative/shift/biwise binary
3831  /// expression.
3832  NotABinaryOperator,
3833  /// \brief RHS binary operation does not have reference to the updated LHS
3834  /// part.
3835  NotAnUpdateExpression,
3836  /// \brief No errors is found.
3837  NoError
3838  };
3839  /// \brief Reference to Sema.
3840  Sema &SemaRef;
3841  /// \brief A location for note diagnostics (when error is found).
3842  SourceLocation NoteLoc;
3843  /// \brief 'x' lvalue part of the source atomic expression.
3844  Expr *X;
3845  /// \brief 'expr' rvalue part of the source atomic expression.
3846  Expr *E;
3847  /// \brief Helper expression of the form
3848  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3849  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3850  Expr *UpdateExpr;
3851  /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
3852  /// important for non-associative operations.
3853  bool IsXLHSInRHSPart;
3854  BinaryOperatorKind Op;
3855  SourceLocation OpLoc;
3856  /// \brief true if the source expression is a postfix unary operation, false
3857  /// if it is a prefix unary operation.
3858  bool IsPostfixUpdate;
3859 
3860 public:
3861  OpenMPAtomicUpdateChecker(Sema &SemaRef)
3862  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
3863  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
3864  /// \brief Check specified statement that it is suitable for 'atomic update'
3865  /// constructs and extract 'x', 'expr' and Operation from the original
3866  /// expression. If DiagId and NoteId == 0, then only check is performed
3867  /// without error notification.
3868  /// \param DiagId Diagnostic which should be emitted if error is found.
3869  /// \param NoteId Diagnostic note for the main error message.
3870  /// \return true if statement is not an update expression, false otherwise.
3871  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
3872  /// \brief Return the 'x' lvalue part of the source atomic expression.
3873  Expr *getX() const { return X; }
3874  /// \brief Return the 'expr' rvalue part of the source atomic expression.
3875  Expr *getExpr() const { return E; }
3876  /// \brief Return the update expression used in calculation of the updated
3877  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3878  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3879  Expr *getUpdateExpr() const { return UpdateExpr; }
3880  /// \brief Return true if 'x' is LHS in RHS part of full update expression,
3881  /// false otherwise.
3882  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
3883 
3884  /// \brief true if the source expression is a postfix unary operation, false
3885  /// if it is a prefix unary operation.
3886  bool isPostfixUpdate() const { return IsPostfixUpdate; }
3887 
3888 private:
3889  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
3890  unsigned NoteId = 0);
3891 };
3892 } // namespace
3893 
3894 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
3895  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
3896  ExprAnalysisErrorCode ErrorFound = NoError;
3897  SourceLocation ErrorLoc, NoteLoc;
3898  SourceRange ErrorRange, NoteRange;
3899  // Allowed constructs are:
3900  // x = x binop expr;
3901  // x = expr binop x;
3902  if (AtomicBinOp->getOpcode() == BO_Assign) {
3903  X = AtomicBinOp->getLHS();
3904  if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
3905  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
3906  if (AtomicInnerBinOp->isMultiplicativeOp() ||
3907  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
3908  AtomicInnerBinOp->isBitwiseOp()) {
3909  Op = AtomicInnerBinOp->getOpcode();
3910  OpLoc = AtomicInnerBinOp->getOperatorLoc();
3911  auto *LHS = AtomicInnerBinOp->getLHS();
3912  auto *RHS = AtomicInnerBinOp->getRHS();
3913  llvm::FoldingSetNodeID XId, LHSId, RHSId;
3914  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
3915  /*Canonical=*/true);
3916  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
3917  /*Canonical=*/true);
3918  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
3919  /*Canonical=*/true);
3920  if (XId == LHSId) {
3921  E = RHS;
3922  IsXLHSInRHSPart = true;
3923  } else if (XId == RHSId) {
3924  E = LHS;
3925  IsXLHSInRHSPart = false;
3926  } else {
3927  ErrorLoc = AtomicInnerBinOp->getExprLoc();
3928  ErrorRange = AtomicInnerBinOp->getSourceRange();
3929  NoteLoc = X->getExprLoc();
3930  NoteRange = X->getSourceRange();
3931  ErrorFound = NotAnUpdateExpression;
3932  }
3933  } else {
3934  ErrorLoc = AtomicInnerBinOp->getExprLoc();
3935  ErrorRange = AtomicInnerBinOp->getSourceRange();
3936  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
3937  NoteRange = SourceRange(NoteLoc, NoteLoc);
3938  ErrorFound = NotABinaryOperator;
3939  }
3940  } else {
3941  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
3942  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
3943  ErrorFound = NotABinaryExpression;
3944  }
3945  } else {
3946  ErrorLoc = AtomicBinOp->getExprLoc();
3947  ErrorRange = AtomicBinOp->getSourceRange();
3948  NoteLoc = AtomicBinOp->getOperatorLoc();
3949  NoteRange = SourceRange(NoteLoc, NoteLoc);
3950  ErrorFound = NotAnAssignmentOp;
3951  }
3952  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
3953  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
3954  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
3955  return true;
3956  } else if (SemaRef.CurContext->isDependentContext())
3957  E = X = UpdateExpr = nullptr;
3958  return ErrorFound != NoError;
3959 }
3960 
3961 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
3962  unsigned NoteId) {
3963  ExprAnalysisErrorCode ErrorFound = NoError;
3964  SourceLocation ErrorLoc, NoteLoc;
3965  SourceRange ErrorRange, NoteRange;
3966  // Allowed constructs are:
3967  // x++;
3968  // x--;
3969  // ++x;
3970  // --x;
3971  // x binop= expr;
3972  // x = x binop expr;
3973  // x = expr binop x;
3974  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
3975  AtomicBody = AtomicBody->IgnoreParenImpCasts();
3976  if (AtomicBody->getType()->isScalarType() ||
3977  AtomicBody->isInstantiationDependent()) {
3978  if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
3979  AtomicBody->IgnoreParenImpCasts())) {
3980  // Check for Compound Assignment Operation
3982  AtomicCompAssignOp->getOpcode());
3983  OpLoc = AtomicCompAssignOp->getOperatorLoc();
3984  E = AtomicCompAssignOp->getRHS();
3985  X = AtomicCompAssignOp->getLHS();
3986  IsXLHSInRHSPart = true;
3987  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
3988  AtomicBody->IgnoreParenImpCasts())) {
3989  // Check for Binary Operation
3990  if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
3991  return true;
3992  } else if (auto *AtomicUnaryOp =
3993  dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) {
3994  // Check for Unary Operation
3995  if (AtomicUnaryOp->isIncrementDecrementOp()) {
3996  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
3997  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
3998  OpLoc = AtomicUnaryOp->getOperatorLoc();
3999  X = AtomicUnaryOp->getSubExpr();
4000  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
4001  IsXLHSInRHSPart = true;
4002  } else {
4003  ErrorFound = NotAnUnaryIncDecExpression;
4004  ErrorLoc = AtomicUnaryOp->getExprLoc();
4005  ErrorRange = AtomicUnaryOp->getSourceRange();
4006  NoteLoc = AtomicUnaryOp->getOperatorLoc();
4007  NoteRange = SourceRange(NoteLoc, NoteLoc);
4008  }
4009  } else {
4010  ErrorFound = NotABinaryOrUnaryExpression;
4011  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
4012  NoteRange = ErrorRange = AtomicBody->getSourceRange();
4013  }
4014  } else {
4015  ErrorFound = NotAScalarType;
4016  NoteLoc = ErrorLoc = AtomicBody->getLocStart();
4017  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
4018  }
4019  } else {
4020  ErrorFound = NotAnExpression;
4021  NoteLoc = ErrorLoc = S->getLocStart();
4022  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
4023  }
4024  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
4025  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
4026  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
4027  return true;
4028  } else if (SemaRef.CurContext->isDependentContext())
4029  E = X = UpdateExpr = nullptr;
4030  if (ErrorFound == NoError && E && X) {
4031  // Build an update expression of form 'OpaqueValueExpr(x) binop
4032  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
4033  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
4034  auto *OVEX = new (SemaRef.getASTContext())
4035  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
4036  auto *OVEExpr = new (SemaRef.getASTContext())
4038  auto Update =
4039  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
4040  IsXLHSInRHSPart ? OVEExpr : OVEX);
4041  if (Update.isInvalid())
4042  return true;
4043  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
4045  if (Update.isInvalid())
4046  return true;
4047  UpdateExpr = Update.get();
4048  }
4049  return ErrorFound != NoError;
4050 }
4051 
4053  Stmt *AStmt,
4054  SourceLocation StartLoc,
4055  SourceLocation EndLoc) {
4056  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
4057  auto CS = cast<CapturedStmt>(AStmt);
4058  // 1.2.2 OpenMP Language Terminology
4059  // Structured block - An executable statement with a single entry at the
4060  // top and a single exit at the bottom.
4061  // The point of exit cannot be a branch out of the structured block.
4062  // longjmp() and throw() must not violate the entry/exit criteria.
4063  OpenMPClauseKind AtomicKind = OMPC_unknown;
4064  SourceLocation AtomicKindLoc;
4065  for (auto *C : Clauses) {
4066  if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
4067  C->getClauseKind() == OMPC_update ||
4068  C->getClauseKind() == OMPC_capture) {
4069  if (AtomicKind != OMPC_unknown) {
4070  Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
4071  << SourceRange(C->getLocStart(), C->getLocEnd());
4072  Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
4073  << getOpenMPClauseName(AtomicKind);
4074  } else {
4075  AtomicKind = C->getClauseKind();
4076  AtomicKindLoc = C->getLocStart();
4077  }
4078  }
4079  }
4080 
4081  auto Body = CS->getCapturedStmt();
4082  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
4083  Body = EWC->getSubExpr();
4084 
4085  Expr *X = nullptr;
4086  Expr *V = nullptr;
4087  Expr *E = nullptr;
4088  Expr *UE = nullptr;
4089  bool IsXLHSInRHSPart = false;
4090  bool IsPostfixUpdate = false;
4091  // OpenMP [2.12.6, atomic Construct]
4092  // In the next expressions:
4093  // * x and v (as applicable) are both l-value expressions with scalar type.
4094  // * During the execution of an atomic region, multiple syntactic
4095  // occurrences of x must designate the same storage location.
4096  // * Neither of v and expr (as applicable) may access the storage location
4097  // designated by x.
4098  // * Neither of x and expr (as applicable) may access the storage location
4099  // designated by v.
4100  // * expr is an expression with scalar type.
4101  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
4102  // * binop, binop=, ++, and -- are not overloaded operators.
4103  // * The expression x binop expr must be numerically equivalent to x binop
4104  // (expr). This requirement is satisfied if the operators in expr have
4105  // precedence greater than binop, or by using parentheses around expr or
4106  // subexpressions of expr.
4107  // * The expression expr binop x must be numerically equivalent to (expr)
4108  // binop x. This requirement is satisfied if the operators in expr have
4109  // precedence equal to or greater than binop, or by using parentheses around
4110  // expr or subexpressions of expr.
4111  // * For forms that allow multiple occurrences of x, the number of times
4112  // that x is evaluated is unspecified.
4113  if (AtomicKind == OMPC_read) {
4114  enum {
4115  NotAnExpression,
4116  NotAnAssignmentOp,
4117  NotAScalarType,
4118  NotAnLValue,
4119  NoError
4120  } ErrorFound = NoError;
4121  SourceLocation ErrorLoc, NoteLoc;
4122  SourceRange ErrorRange, NoteRange;
4123  // If clause is read:
4124  // v = x;
4125  if (auto AtomicBody = dyn_cast<Expr>(Body)) {
4126  auto AtomicBinOp =
4127  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
4128  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
4129  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
4130  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
4131  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
4132  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
4133  if (!X->isLValue() || !V->isLValue()) {
4134  auto NotLValueExpr = X->isLValue() ? V : X;
4135  ErrorFound = NotAnLValue;
4136  ErrorLoc = AtomicBinOp->getExprLoc();
4137  ErrorRange = AtomicBinOp->getSourceRange();
4138  NoteLoc = NotLValueExpr->getExprLoc();
4139  NoteRange = NotLValueExpr->getSourceRange();
4140  }
4141  } else if (!X->isInstantiationDependent() ||
4142  !V->isInstantiationDependent()) {
4143  auto NotScalarExpr =
4145  ? V
4146  : X;
4147  ErrorFound = NotAScalarType;
4148  ErrorLoc = AtomicBinOp->getExprLoc();
4149  ErrorRange = AtomicBinOp->getSourceRange();
4150  NoteLoc = NotScalarExpr->getExprLoc();
4151  NoteRange = NotScalarExpr->getSourceRange();
4152  }
4153  } else {
4154  ErrorFound = NotAnAssignmentOp;
4155  ErrorLoc = AtomicBody->getExprLoc();
4156  ErrorRange = AtomicBody->getSourceRange();
4157  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
4158  : AtomicBody->getExprLoc();
4159  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
4160  : AtomicBody->getSourceRange();
4161  }
4162  } else {
4163  ErrorFound = NotAnExpression;
4164  NoteLoc = ErrorLoc = Body->getLocStart();
4165  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
4166  }
4167  if (ErrorFound != NoError) {
4168  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
4169  << ErrorRange;
4170  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
4171  << NoteRange;
4172  return StmtError();
4173  } else if (CurContext->isDependentContext())
4174  V = X = nullptr;
4175  } else if (AtomicKind == OMPC_write) {
4176  enum {
4177  NotAnExpression,
4178  NotAnAssignmentOp,
4179  NotAScalarType,
4180  NotAnLValue,
4181  NoError
4182  } ErrorFound = NoError;
4183  SourceLocation ErrorLoc, NoteLoc;
4184  SourceRange ErrorRange, NoteRange;
4185  // If clause is write:
4186  // x = expr;
4187  if (auto AtomicBody = dyn_cast<Expr>(Body)) {
4188  auto AtomicBinOp =
4189  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
4190  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
4191  X = AtomicBinOp->getLHS();
4192  E = AtomicBinOp->getRHS();
4193  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
4194  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
4195  if (!X->isLValue()) {
4196  ErrorFound = NotAnLValue;
4197  ErrorLoc = AtomicBinOp->getExprLoc();
4198  ErrorRange = AtomicBinOp->getSourceRange();
4199  NoteLoc = X->getExprLoc();
4200  NoteRange = X->getSourceRange();
4201  }
4202  } else if (!X->isInstantiationDependent() ||
4203  !E->isInstantiationDependent()) {
4204  auto NotScalarExpr =
4206  ? E
4207  : X;
4208  ErrorFound = NotAScalarType;
4209  ErrorLoc = AtomicBinOp->getExprLoc();
4210  ErrorRange = AtomicBinOp->getSourceRange();
4211  NoteLoc = NotScalarExpr->getExprLoc();
4212  NoteRange = NotScalarExpr->getSourceRange();
4213  }
4214  } else {
4215  ErrorFound = NotAnAssignmentOp;
4216  ErrorLoc = AtomicBody->getExprLoc();
4217  ErrorRange = AtomicBody->getSourceRange();
4218  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
4219  : AtomicBody->getExprLoc();
4220  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
4221  : AtomicBody->getSourceRange();
4222  }
4223  } else {
4224  ErrorFound = NotAnExpression;
4225  NoteLoc = ErrorLoc = Body->getLocStart();
4226  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
4227  }
4228  if (ErrorFound != NoError) {
4229  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
4230  << ErrorRange;
4231  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
4232  << NoteRange;
4233  return StmtError();
4234  } else if (CurContext->isDependentContext())
4235  E = X = nullptr;
4236  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
4237  // If clause is update:
4238  // x++;
4239  // x--;
4240  // ++x;
4241  // --x;
4242  // x binop= expr;
4243  // x = x binop expr;
4244  // x = expr binop x;
4245  OpenMPAtomicUpdateChecker Checker(*this);
4246  if (Checker.checkStatement(
4247  Body, (AtomicKind == OMPC_update)
4248  ? diag::err_omp_atomic_update_not_expression_statement
4249  : diag::err_omp_atomic_not_expression_statement,
4250  diag::note_omp_atomic_update))
4251  return StmtError();
4252  if (!CurContext->isDependentContext()) {
4253  E = Checker.getExpr();
4254  X = Checker.getX();
4255  UE = Checker.getUpdateExpr();
4256  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
4257  }
4258  } else if (AtomicKind == OMPC_capture) {
4259  enum {
4260  NotAnAssignmentOp,
4261  NotACompoundStatement,
4262  NotTwoSubstatements,
4263  NotASpecificExpression,
4264  NoError
4265  } ErrorFound = NoError;
4266  SourceLocation ErrorLoc, NoteLoc;
4267  SourceRange ErrorRange, NoteRange;
4268  if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
4269  // If clause is a capture:
4270  // v = x++;
4271  // v = x--;
4272  // v = ++x;
4273  // v = --x;
4274  // v = x binop= expr;
4275  // v = x = x binop expr;
4276  // v = x = expr binop x;
4277  auto *AtomicBinOp =
4278  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
4279  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
4280  V = AtomicBinOp->getLHS();
4281  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
4282  OpenMPAtomicUpdateChecker Checker(*this);
4283  if (Checker.checkStatement(
4284  Body, diag::err_omp_atomic_capture_not_expression_statement,
4285  diag::note_omp_atomic_update))
4286  return StmtError();
4287  E = Checker.getExpr();
4288  X = Checker.getX();
4289  UE = Checker.getUpdateExpr();
4290  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
4291  IsPostfixUpdate = Checker.isPostfixUpdate();
4292  } else {
4293  ErrorLoc = AtomicBody->getExprLoc();
4294  ErrorRange = AtomicBody->getSourceRange();
4295  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
4296  : AtomicBody->getExprLoc();
4297  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
4298  : AtomicBody->getSourceRange();
4299  ErrorFound = NotAnAssignmentOp;
4300  }
4301  if (ErrorFound != NoError) {
4302  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
4303  << ErrorRange;
4304  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
4305  return StmtError();
4306  } else if (CurContext->isDependentContext()) {
4307  UE = V = E = X = nullptr;
4308  }
4309  } else {
4310  // If clause is a capture:
4311  // { v = x; x = expr; }
4312  // { v = x; x++; }
4313  // { v = x; x--; }
4314  // { v = x; ++x; }
4315  // { v = x; --x; }
4316  // { v = x; x binop= expr; }
4317  // { v = x; x = x binop expr; }
4318  // { v = x; x = expr binop x; }
4319  // { x++; v = x; }
4320  // { x--; v = x; }
4321  // { ++x; v = x; }
4322  // { --x; v = x; }
4323  // { x binop= expr; v = x; }
4324  // { x = x binop expr; v = x; }
4325  // { x = expr binop x; v = x; }
4326  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
4327  // Check that this is { expr1; expr2; }
4328  if (CS->size() == 2) {
4329  auto *First = CS->body_front();
4330  auto *Second = CS->body_back();
4331  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
4332  First = EWC->getSubExpr()->IgnoreParenImpCasts();
4333  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
4334  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
4335  // Need to find what subexpression is 'v' and what is 'x'.
4336  OpenMPAtomicUpdateChecker Checker(*this);
4337  bool IsUpdateExprFound = !Checker.checkStatement(Second);
4338  BinaryOperator *BinOp = nullptr;
4339  if (IsUpdateExprFound) {
4340  BinOp = dyn_cast<BinaryOperator>(First);
4341  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
4342  }
4343  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
4344  // { v = x; x++; }
4345  // { v = x; x--; }
4346  // { v = x; ++x; }
4347  // { v = x; --x; }
4348  // { v = x; x binop= expr; }
4349  // { v = x; x = x binop expr; }
4350  // { v = x; x = expr binop x; }
4351  // Check that the first expression has form v = x.
4352  auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
4353  llvm::FoldingSetNodeID XId, PossibleXId;
4354  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
4355  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
4356  IsUpdateExprFound = XId == PossibleXId;
4357  if (IsUpdateExprFound) {
4358  V = BinOp->getLHS();
4359  X = Checker.getX();
4360  E = Checker.getExpr();
4361  UE = Checker.getUpdateExpr();
4362  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
4363  IsPostfixUpdate = true;
4364  }
4365  }
4366  if (!IsUpdateExprFound) {
4367  IsUpdateExprFound = !Checker.checkStatement(First);
4368  BinOp = nullptr;
4369  if (IsUpdateExprFound) {
4370  BinOp = dyn_cast<BinaryOperator>(Second);
4371  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
4372  }
4373  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
4374  // { x++; v = x; }
4375  // { x--; v = x; }
4376  // { ++x; v = x; }
4377  // { --x; v = x; }
4378  // { x binop= expr; v = x; }
4379  // { x = x binop expr; v = x; }
4380  // { x = expr binop x; v = x; }
4381  // Check that the second expression has form v = x.
4382  auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
4383  llvm::FoldingSetNodeID XId, PossibleXId;
4384  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
4385  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
4386  IsUpdateExprFound = XId == PossibleXId;
4387  if (IsUpdateExprFound) {
4388  V = BinOp->getLHS();
4389  X = Checker.getX();
4390  E = Checker.getExpr();
4391  UE = Checker.getUpdateExpr();
4392  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
4393  IsPostfixUpdate = false;
4394  }
4395  }
4396  }
4397  if (!IsUpdateExprFound) {
4398  // { v = x; x = expr; }
4399  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
4400  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
4401  ErrorFound = NotAnAssignmentOp;
4402  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
4403  : First->getLocStart();
4404  NoteRange = ErrorRange = FirstBinOp
4405  ? FirstBinOp->getSourceRange()
4406  : SourceRange(ErrorLoc, ErrorLoc);
4407  } else {
4408  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
4409  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
4410  ErrorFound = NotAnAssignmentOp;
4411  NoteLoc = ErrorLoc = SecondBinOp ? SecondBinOp->getOperatorLoc()
4412  : Second->getLocStart();
4413  NoteRange = ErrorRange = SecondBinOp
4414  ? SecondBinOp->getSourceRange()
4415  : SourceRange(ErrorLoc, ErrorLoc);
4416  } else {
4417  auto *PossibleXRHSInFirst =
4418  FirstBinOp->getRHS()->IgnoreParenImpCasts();
4419  auto *PossibleXLHSInSecond =
4420  SecondBinOp->getLHS()->IgnoreParenImpCasts();
4421  llvm::FoldingSetNodeID X1Id, X2Id;
4422  PossibleXRHSInFirst->Profile(X1Id, Context, /*Canonical=*/true);
4423  PossibleXLHSInSecond->Profile(X2Id, Context,
4424  /*Canonical=*/true);
4425  IsUpdateExprFound = X1Id == X2Id;
4426  if (IsUpdateExprFound) {
4427  V = FirstBinOp->getLHS();
4428  X = SecondBinOp->getLHS();
4429  E = SecondBinOp->getRHS();
4430  UE = nullptr;
4431  IsXLHSInRHSPart = false;
4432  IsPostfixUpdate = true;
4433  } else {
4434  ErrorFound = NotASpecificExpression;
4435  ErrorLoc = FirstBinOp->getExprLoc();
4436  ErrorRange = FirstBinOp->getSourceRange();
4437  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
4438  NoteRange = SecondBinOp->getRHS()->getSourceRange();
4439  }
4440  }
4441  }
4442  }
4443  } else {
4444  NoteLoc = ErrorLoc = Body->getLocStart();
4445  NoteRange = ErrorRange =
4446  SourceRange(Body->getLocStart(), Body->getLocStart());
4447  ErrorFound = NotTwoSubstatements;
4448  }
4449  } else {
4450  NoteLoc = ErrorLoc = Body->getLocStart();
4451  NoteRange = ErrorRange =
4452  SourceRange(Body->getLocStart(), Body->getLocStart());
4453  ErrorFound = NotACompoundStatement;
4454  }
4455  if (ErrorFound != NoError) {
4456  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
4457  << ErrorRange;
4458  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
4459  return StmtError();
4460  } else if (CurContext->isDependentContext()) {
4461  UE = V = E = X = nullptr;
4462  }
4463  }
4464  }
4465 
4467 
4468  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
4469  X, V, E, UE, IsXLHSInRHSPart,
4470  IsPostfixUpdate);
4471 }
4472 
4474  Stmt *AStmt,
4475  SourceLocation StartLoc,
4476  SourceLocation EndLoc) {
4477  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
4478 
4479  // OpenMP [2.16, Nesting of Regions]
4480  // If specified, a teams construct must be contained within a target
4481  // construct. That target construct must contain no statements or directives
4482  // outside of the teams construct.
4483  if (DSAStack->hasInnerTeamsRegion()) {
4484  auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true);
4485  bool OMPTeamsFound = true;
4486  if (auto *CS = dyn_cast<CompoundStmt>(S)) {
4487  auto I = CS->body_begin();
4488  while (I != CS->body_end()) {
4489  auto OED = dyn_cast<OMPExecutableDirective>(*I);
4490  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
4491  OMPTeamsFound = false;
4492  break;
4493  }
4494  ++I;
4495  }
4496  assert(I != CS->body_end() && "Not found statement");
4497  S = *I;
4498  }
4499  if (!OMPTeamsFound) {
4500  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
4501  Diag(DSAStack->getInnerTeamsRegionLoc(),
4502  diag::note_omp_nested_teams_construct_here);
4503  Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
4504  << isa<OMPExecutableDirective>(S);
4505  return StmtError();
4506  }
4507  }
4508 
4510 
4511  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
4512 }
4513 
4515  Stmt *AStmt, SourceLocation StartLoc,
4516  SourceLocation EndLoc) {
4517  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
4518  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
4519  // 1.2.2 OpenMP Language Terminology
4520  // Structured block - An executable statement with a single entry at the
4521  // top and a single exit at the bottom.
4522  // The point of exit cannot be a branch out of the structured block.
4523  // longjmp() and throw() must not violate the entry/exit criteria.
4524  CS->getCapturedDecl()->setNothrow();
4525 
4527 
4528  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
4529 }
4530 
4531 StmtResult
4533  SourceLocation EndLoc,
4534  OpenMPDirectiveKind CancelRegion) {
4535  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
4536  CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
4537  Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4538  << getOpenMPDirectiveName(CancelRegion);
4539  return StmtError();
4540  }
4541  if (DSAStack->isParentNowaitRegion()) {
4542  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
4543  return StmtError();
4544  }
4545  if (DSAStack->isParentOrderedRegion()) {
4546  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
4547  return StmtError();
4548  }
4549  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
4550  CancelRegion);
4551 }
4552 
4554  SourceLocation EndLoc,
4555  OpenMPDirectiveKind CancelRegion) {
4556  if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
4557  CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
4558  Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4559  << getOpenMPDirectiveName(CancelRegion);
4560  return StmtError();
4561  }
4562  if (DSAStack->isParentNowaitRegion()) {
4563  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
4564  return StmtError();
4565  }
4566  if (DSAStack->isParentOrderedRegion()) {
4567  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
4568  return StmtError();
4569  }
4570  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, CancelRegion);
4571 }
4572 
4574  SourceLocation StartLoc,
4575  SourceLocation LParenLoc,
4576  SourceLocation EndLoc) {
4577  OMPClause *Res = nullptr;
4578  switch (Kind) {
4579  case OMPC_if:
4580  Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc);
4581  break;
4582  case OMPC_final:
4583  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
4584  break;
4585  case OMPC_num_threads:
4586  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
4587  break;
4588  case OMPC_safelen:
4589  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
4590  break;
4591  case OMPC_collapse:
4592  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
4593  break;
4594  case OMPC_default:
4595  case OMPC_proc_bind:
4596  case OMPC_schedule:
4597  case OMPC_private:
4598  case OMPC_firstprivate:
4599  case OMPC_lastprivate:
4600  case OMPC_shared:
4601  case OMPC_reduction:
4602  case OMPC_linear:
4603  case OMPC_aligned:
4604  case OMPC_copyin:
4605  case OMPC_copyprivate:
4606  case OMPC_ordered:
4607  case OMPC_nowait:
4608  case OMPC_untied:
4609  case OMPC_mergeable:
4610  case OMPC_threadprivate:
4611  case OMPC_flush:
4612  case OMPC_read:
4613  case OMPC_write:
4614  case OMPC_update:
4615  case OMPC_capture:
4616  case OMPC_seq_cst:
4617  case OMPC_depend:
4618  case OMPC_unknown:
4619  llvm_unreachable("Clause is not allowed.");
4620  }
4621  return Res;
4622 }
4623 
4625  SourceLocation LParenLoc,
4626  SourceLocation EndLoc) {
4627  Expr *ValExpr = Condition;
4628  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
4629  !Condition->isInstantiationDependent() &&
4630  !Condition->containsUnexpandedParameterPack()) {
4631  ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
4632  Condition->getExprLoc(), Condition);
4633  if (Val.isInvalid())
4634  return nullptr;
4635 
4636  ValExpr = Val.get();
4637  }
4638 
4639  return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc);
4640 }
4641 
4643  SourceLocation StartLoc,
4644  SourceLocation LParenLoc,
4645  SourceLocation EndLoc) {
4646  Expr *ValExpr = Condition;
4647  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
4648  !Condition->isInstantiationDependent() &&
4649  !Condition->containsUnexpandedParameterPack()) {
4650  ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
4651  Condition->getExprLoc(), Condition);
4652  if (Val.isInvalid())
4653  return nullptr;
4654 
4655  ValExpr = Val.get();
4656  }
4657 
4658  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
4659 }
4661  Expr *Op) {
4662  if (!Op)
4663  return ExprError();
4664 
4665  class IntConvertDiagnoser : public ICEConvertDiagnoser {
4666  public:
4667  IntConvertDiagnoser()
4668  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
4669  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
4670  QualType T) override {
4671  return S.Diag(Loc, diag::err_omp_not_integral) << T;
4672  }
4673  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
4674  QualType T) override {
4675  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
4676  }
4677  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
4678  QualType T,
4679  QualType ConvTy) override {
4680  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
4681  }
4682  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
4683  QualType ConvTy) override {
4684  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
4685  << ConvTy->isEnumeralType() << ConvTy;
4686  }
4687  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
4688  QualType T) override {
4689  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
4690  }
4691  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
4692  QualType ConvTy) override {
4693  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
4694  << ConvTy->isEnumeralType() << ConvTy;
4695  }
4696  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
4697  QualType) override {
4698  llvm_unreachable("conversion functions are permitted");
4699  }
4700  } ConvertDiagnoser;
4701  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
4702 }
4703 
4705  SourceLocation StartLoc,
4706  SourceLocation LParenLoc,
4707  SourceLocation EndLoc) {
4708  Expr *ValExpr = NumThreads;
4709  if (!NumThreads->isValueDependent() && !NumThreads->isTypeDependent() &&
4710  !NumThreads->containsUnexpandedParameterPack()) {
4711  SourceLocation NumThreadsLoc = NumThreads->getLocStart();
4712  ExprResult Val =
4713  PerformOpenMPImplicitIntegerConversion(NumThreadsLoc, NumThreads);
4714  if (Val.isInvalid())
4715  return nullptr;
4716 
4717  ValExpr = Val.get();
4718 
4719  // OpenMP [2.5, Restrictions]
4720  // The num_threads expression must evaluate to a positive integer value.
4721  llvm::APSInt Result;
4722  if (ValExpr->isIntegerConstantExpr(Result, Context) && Result.isSigned() &&
4723  !Result.isStrictlyPositive()) {
4724  Diag(NumThreadsLoc, diag::err_omp_negative_expression_in_clause)
4725  << "num_threads" << NumThreads->getSourceRange();
4726  return nullptr;
4727  }
4728  }
4729 
4730  return new (Context)
4731  OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
4732 }
4733 
4734 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
4735  OpenMPClauseKind CKind) {
4736  if (!E)
4737  return ExprError();
4738  if (E->isValueDependent() || E->isTypeDependent() ||
4740  return E;
4741  llvm::APSInt Result;
4742  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
4743  if (ICE.isInvalid())
4744  return ExprError();
4745  if (!Result.isStrictlyPositive()) {
4746  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
4747  << getOpenMPClauseName(CKind) << E->getSourceRange();
4748  return ExprError();
4749  }
4750  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
4751  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
4752  << E->getSourceRange();
4753  return ExprError();
4754  }
4755  if (CKind == OMPC_collapse) {
4756  DSAStack->setCollapseNumber(Result.getExtValue());
4757  }
4758  return ICE;
4759 }
4760 
4762  SourceLocation LParenLoc,
4763  SourceLocation EndLoc) {
4764  // OpenMP [2.8.1, simd construct, Description]
4765  // The parameter of the safelen clause must be a constant
4766  // positive integer expression.
4767  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
4768  if (Safelen.isInvalid())
4769  return nullptr;
4770  return new (Context)
4771  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
4772 }
4773 
4775  SourceLocation StartLoc,
4776  SourceLocation LParenLoc,
4777  SourceLocation EndLoc) {
4778  // OpenMP [2.7.1, loop construct, Description]
4779  // OpenMP [2.8.1, simd construct, Description]
4780  // OpenMP [2.9.6, distribute construct, Description]
4781  // The parameter of the collapse clause must be a constant
4782  // positive integer expression.
4783  ExprResult NumForLoopsResult =
4784  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
4785  if (NumForLoopsResult.isInvalid())
4786  return nullptr;
4787  return new (Context)
4788  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
4789 }
4790 
4792  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
4793  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
4794  OMPClause *Res = nullptr;
4795  switch (Kind) {
4796  case OMPC_default:
4797  Res =
4798  ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
4799  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
4800  break;
4801  case OMPC_proc_bind:
4803  static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
4804  LParenLoc, EndLoc);
4805  break;
4806  case OMPC_if:
4807  case OMPC_final:
4808  case OMPC_num_threads:
4809  case OMPC_safelen:
4810  case OMPC_collapse:
4811  case OMPC_schedule:
4812  case OMPC_private:
4813  case OMPC_firstprivate:
4814  case OMPC_lastprivate:
4815  case OMPC_shared:
4816  case OMPC_reduction:
4817  case OMPC_linear:
4818  case OMPC_aligned:
4819  case OMPC_copyin:
4820  case OMPC_copyprivate:
4821  case OMPC_ordered:
4822  case OMPC_nowait:
4823  case OMPC_untied:
4824  case OMPC_mergeable:
4825  case OMPC_threadprivate:
4826  case OMPC_flush:
4827  case OMPC_read:
4828  case OMPC_write:
4829  case OMPC_update:
4830  case OMPC_capture:
4831  case OMPC_seq_cst:
4832  case OMPC_depend:
4833  case OMPC_unknown:
4834  llvm_unreachable("Clause is not allowed.");
4835  }
4836  return Res;
4837 }
4838 
4840  SourceLocation KindKwLoc,
4841  SourceLocation StartLoc,
4842  SourceLocation LParenLoc,
4843  SourceLocation EndLoc) {
4844  if (Kind == OMPC_DEFAULT_unknown) {
4845  std::string Values;
4846  static_assert(OMPC_DEFAULT_unknown > 0,
4847  "OMPC_DEFAULT_unknown not greater than 0");
4848  std::string Sep(", ");
4849  for (unsigned i = 0; i < OMPC_DEFAULT_unknown; ++i) {
4850  Values += "'";
4851  Values += getOpenMPSimpleClauseTypeName(OMPC_default, i);
4852  Values += "'";
4853  switch (i) {
4854  case OMPC_DEFAULT_unknown - 2:
4855  Values += " or ";
4856  break;
4857  case OMPC_DEFAULT_unknown - 1:
4858  break;
4859  default:
4860  Values += Sep;
4861  break;
4862  }
4863  }
4864  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
4865  << Values << getOpenMPClauseName(OMPC_default);
4866  return nullptr;
4867  }
4868  switch (Kind) {
4869  case OMPC_DEFAULT_none:
4870  DSAStack->setDefaultDSANone(KindKwLoc);
4871  break;
4872  case OMPC_DEFAULT_shared:
4873  DSAStack->setDefaultDSAShared(KindKwLoc);
4874  break;
4875  case OMPC_DEFAULT_unknown:
4876  llvm_unreachable("Clause kind is not allowed.");
4877  break;
4878  }
4879  return new (Context)
4880  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
4881 }
4882 
4884  SourceLocation KindKwLoc,
4885  SourceLocation StartLoc,
4886  SourceLocation LParenLoc,
4887  SourceLocation EndLoc) {
4888  if (Kind == OMPC_PROC_BIND_unknown) {
4889  std::string Values;
4890  std::string Sep(", ");
4891  for (unsigned i = 0; i < OMPC_PROC_BIND_unknown; ++i) {
4892  Values += "'";
4893  Values += getOpenMPSimpleClauseTypeName(OMPC_proc_bind, i);
4894  Values += "'";
4895  switch (i) {
4896  case OMPC_PROC_BIND_unknown - 2:
4897  Values += " or ";
4898  break;
4899  case OMPC_PROC_BIND_unknown - 1:
4900  break;
4901  default:
4902  Values += Sep;
4903  break;
4904  }
4905  }
4906  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
4907  << Values << getOpenMPClauseName(OMPC_proc_bind);
4908  return nullptr;
4909  }
4910  return new (Context)
4911  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
4912 }
4913 
4915  OpenMPClauseKind Kind, unsigned Argument, Expr *Expr,
4916  SourceLocation StartLoc, SourceLocation LParenLoc,
4917  SourceLocation ArgumentLoc, SourceLocation CommaLoc,
4918  SourceLocation EndLoc) {
4919  OMPClause *Res = nullptr;
4920  switch (Kind) {
4921  case OMPC_schedule:
4923  static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc,
4924  LParenLoc, ArgumentLoc, CommaLoc, EndLoc);
4925  break;
4926  case OMPC_if:
4927  case OMPC_final:
4928  case OMPC_num_threads:
4929  case OMPC_safelen:
4930  case OMPC_collapse:
4931  case OMPC_default:
4932  case OMPC_proc_bind:
4933  case OMPC_private:
4934  case OMPC_firstprivate:
4935  case OMPC_lastprivate:
4936  case OMPC_shared:
4937  case OMPC_reduction:
4938  case OMPC_linear:
4939  case OMPC_aligned:
4940  case OMPC_copyin:
4941  case OMPC_copyprivate:
4942  case OMPC_ordered:
4943  case OMPC_nowait:
4944  case OMPC_untied:
4945  case OMPC_mergeable:
4946  case OMPC_threadprivate:
4947  case OMPC_flush:
4948  case OMPC_read:
4949  case OMPC_write:
4950  case OMPC_update:
4951  case OMPC_capture:
4952  case OMPC_seq_cst:
4953  case OMPC_depend:
4954  case OMPC_unknown:
4955  llvm_unreachable("Clause is not allowed.");
4956  }
4957  return Res;
4958 }
4959 
4961  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
4962  SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
4963  SourceLocation EndLoc) {
4964  if (Kind == OMPC_SCHEDULE_unknown) {
4965  std::string Values;
4966  std::string Sep(", ");
4967  for (unsigned i = 0; i < OMPC_SCHEDULE_unknown; ++i) {
4968  Values += "'";
4969  Values += getOpenMPSimpleClauseTypeName(OMPC_schedule, i);
4970  Values += "'";
4971  switch (i) {
4972  case OMPC_SCHEDULE_unknown - 2:
4973  Values += " or ";
4974  break;
4975  case OMPC_SCHEDULE_unknown - 1:
4976  break;
4977  default:
4978  Values += Sep;
4979  break;
4980  }
4981  }
4982  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
4983  << Values << getOpenMPClauseName(OMPC_schedule);
4984  return nullptr;
4985  }
4986  Expr *ValExpr = ChunkSize;
4987  Expr *HelperValExpr = nullptr;
4988  if (ChunkSize) {
4989  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
4990  !ChunkSize->isInstantiationDependent() &&
4991  !ChunkSize->containsUnexpandedParameterPack()) {
4992  SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
4993  ExprResult Val =
4994  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
4995  if (Val.isInvalid())
4996  return nullptr;
4997 
4998  ValExpr = Val.get();
4999 
5000  // OpenMP [2.7.1, Restrictions]
5001  // chunk_size must be a loop invariant integer expression with a positive
5002  // value.
5003  llvm::APSInt Result;
5004  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
5005  if (Result.isSigned() && !Result.isStrictlyPositive()) {
5006  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
5007  << "schedule" << ChunkSize->getSourceRange();
5008  return nullptr;
5009  }
5010  } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) {
5011  auto *ImpVar = buildVarDecl(*this, ChunkSize->getExprLoc(),
5012  ChunkSize->getType(), ".chunk.");
5013  auto *ImpVarRef = buildDeclRefExpr(*this, ImpVar, ChunkSize->getType(),
5014  ChunkSize->getExprLoc(),
5015  /*RefersToCapture=*/true);
5016  HelperValExpr = ImpVarRef;
5017  }
5018  }
5019  }
5020 
5021  return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc,
5022  EndLoc, Kind, ValExpr, HelperValExpr);
5023 }
5024 
5026  SourceLocation StartLoc,
5027  SourceLocation EndLoc) {
5028  OMPClause *Res = nullptr;
5029  switch (Kind) {
5030  case OMPC_ordered:
5031  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
5032  break;
5033  case OMPC_nowait:
5034  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
5035  break;
5036  case OMPC_untied:
5037  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
5038  break;
5039  case OMPC_mergeable:
5040  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
5041  break;
5042  case OMPC_read:
5043  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
5044  break;
5045  case OMPC_write:
5046  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
5047  break;
5048  case OMPC_update:
5049  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
5050  break;
5051  case OMPC_capture:
5052  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
5053  break;
5054  case OMPC_seq_cst:
5055  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
5056  break;
5057  case OMPC_if:
5058  case OMPC_final:
5059  case OMPC_num_threads:
5060  case OMPC_safelen:
5061  case OMPC_collapse:
5062  case OMPC_schedule:
5063  case OMPC_private:
5064  case OMPC_firstprivate:
5065  case OMPC_lastprivate:
5066  case OMPC_shared:
5067  case OMPC_reduction:
5068  case OMPC_linear:
5069  case OMPC_aligned:
5070  case OMPC_copyin:
5071  case OMPC_copyprivate:
5072  case OMPC_default:
5073  case OMPC_proc_bind:
5074  case OMPC_threadprivate:
5075  case OMPC_flush:
5076  case OMPC_depend:
5077  case OMPC_unknown:
5078  llvm_unreachable("Clause is not allowed.");
5079  }
5080  return Res;
5081 }
5082 
5084  SourceLocation EndLoc) {
5085  DSAStack->setOrderedRegion();
5086  return new (Context) OMPOrderedClause(StartLoc, EndLoc);
5087 }
5088 
5090  SourceLocation EndLoc) {
5091  DSAStack->setNowaitRegion();
5092  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
5093 }
5094 
5096  SourceLocation EndLoc) {
5097  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
5098 }
5099 
5101  SourceLocation EndLoc) {
5102  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
5103 }
5104 
5106  SourceLocation EndLoc) {
5107  return new (Context) OMPReadClause(StartLoc, EndLoc);
5108 }
5109 
5111  SourceLocation EndLoc) {
5112  return new (Context) OMPWriteClause(StartLoc, EndLoc);
5113 }
5114 
5116  SourceLocation EndLoc) {
5117  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
5118 }
5119 
5121  SourceLocation EndLoc) {
5122  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
5123 }
5124 
5126  SourceLocation EndLoc) {
5127  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
5128 }
5129 
5131  OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
5133  SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
5134  const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
5135  SourceLocation DepLoc) {
5136  OMPClause *Res = nullptr;
5137  switch (Kind) {
5138  case OMPC_private:
5139  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
5140  break;
5141  case OMPC_firstprivate:
5142  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
5143  break;
5144  case OMPC_lastprivate:
5145  Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
5146  break;
5147  case OMPC_shared:
5148  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
5149  break;
5150  case OMPC_reduction:
5151  Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
5152  EndLoc, ReductionIdScopeSpec, ReductionId);
5153  break;
5154  case OMPC_linear:
5155  Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
5156  ColonLoc, EndLoc);
5157  break;
5158  case OMPC_aligned:
5159  Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
5160  ColonLoc, EndLoc);
5161  break;
5162  case OMPC_copyin:
5163  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
5164  break;
5165  case OMPC_copyprivate:
5166  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
5167  break;
5168  case OMPC_flush:
5169  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
5170  break;
5171  case OMPC_depend:
5172  Res = ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, StartLoc,
5173  LParenLoc, EndLoc);
5174  break;
5175  case OMPC_if:
5176  case OMPC_final:
5177  case OMPC_num_threads:
5178  case OMPC_safelen:
5179  case OMPC_collapse:
5180  case OMPC_default:
5181  case OMPC_proc_bind:
5182  case OMPC_schedule:
5183  case OMPC_ordered:
5184  case OMPC_nowait:
5185  case OMPC_untied:
5186  case OMPC_mergeable:
5187  case OMPC_threadprivate:
5188  case OMPC_read:
5189  case OMPC_write:
5190  case OMPC_update:
5191  case OMPC_capture:
5192  case OMPC_seq_cst:
5193  case OMPC_unknown:
5194  llvm_unreachable("Clause is not allowed.");
5195  }
5196  return Res;
5197 }
5198 
5200  SourceLocation StartLoc,
5201  SourceLocation LParenLoc,
5202  SourceLocation EndLoc) {
5204  SmallVector<Expr *, 8> PrivateCopies;
5205  for (auto &RefExpr : VarList) {
5206  assert(RefExpr && "NULL expr in OpenMP private clause.");
5207  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5208  // It will be analyzed later.
5209  Vars.push_back(RefExpr);
5210  PrivateCopies.push_back(nullptr);
5211  continue;
5212  }
5213 
5214  SourceLocation ELoc = RefExpr->getExprLoc();
5215  // OpenMP [2.1, C/C++]
5216  // A list item is a variable name.
5217  // OpenMP [2.9.3.3, Restrictions, p.1]
5218  // A variable that is part of another variable (as an array or
5219  // structure element) cannot appear in a private clause.
5220  DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5221  if (!DE || !isa<VarDecl>(DE->getDecl())) {
5222  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
5223  continue;
5224  }
5225  Decl *D = DE->getDecl();
5226  VarDecl *VD = cast<VarDecl>(D);
5227 
5228  QualType Type = VD->getType();
5229  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
5230  // It will be analyzed later.
5231  Vars.push_back(DE);
5232  PrivateCopies.push_back(nullptr);
5233  continue;
5234  }
5235 
5236  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
5237  // A variable that appears in a private clause must not have an incomplete
5238  // type or a reference type.
5239  if (RequireCompleteType(ELoc, Type,
5240  diag::err_omp_private_incomplete_type)) {
5241  continue;
5242  }
5243  if (Type->isReferenceType()) {
5244  Diag(ELoc, diag::err_omp_clause_ref_type_arg)
5245  << getOpenMPClauseName(OMPC_private) << Type;
5246  bool IsDecl =
5248  Diag(VD->getLocation(),
5249  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5250  << VD;
5251  continue;
5252  }
5253 
5254  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
5255  // in a Construct]
5256  // Variables with the predetermined data-sharing attributes may not be
5257  // listed in data-sharing attributes clauses, except for the cases
5258  // listed below. For these exceptions only, listing a predetermined
5259  // variable in a data-sharing attribute clause is allowed and overrides
5260  // the variable's predetermined data-sharing attributes.
5261  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
5262  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
5263  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
5264  << getOpenMPClauseName(OMPC_private);
5265  ReportOriginalDSA(*this, DSAStack, VD, DVar);
5266  continue;
5267  }
5268 
5269  // Variably modified types are not supported for tasks.
5270  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
5271  DSAStack->getCurrentDirective() == OMPD_task) {
5272  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
5273  << getOpenMPClauseName(OMPC_private) << Type
5274  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
5275  bool IsDecl =
5277  Diag(VD->getLocation(),
5278  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5279  << VD;
5280  continue;
5281  }
5282 
5283  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
5284  // A variable of class type (or array thereof) that appears in a private
5285  // clause requires an accessible, unambiguous default constructor for the
5286  // class type.
5287  // Generate helper private variable and initialize it with the default
5288  // value. The address of the original variable is replaced by the address of
5289  // the new private variable in CodeGen. This new variable is not added to
5290  // IdResolver, so the code in the OpenMP region uses original variable for
5291  // proper diagnostics.
5292  Type = Type.getUnqualifiedType();
5293  auto VDPrivate = buildVarDecl(*this, DE->getExprLoc(), Type, VD->getName());
5294  ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
5295  if (VDPrivate->isInvalidDecl())
5296  continue;
5297  auto VDPrivateRefExpr = buildDeclRefExpr(
5298  *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc());
5299 
5300  DSAStack->addDSA(VD, DE, OMPC_private);
5301  Vars.push_back(DE);
5302  PrivateCopies.push_back(VDPrivateRefExpr);
5303  }
5304 
5305  if (Vars.empty())
5306  return nullptr;
5307 
5308  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
5309  PrivateCopies);
5310 }
5311 
5312 namespace {
5313 class DiagsUninitializedSeveretyRAII {
5314 private:
5316  SourceLocation SavedLoc;
5317  bool IsIgnored;
5318 
5319 public:
5320  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
5321  bool IsIgnored)
5322  : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
5323  if (!IsIgnored) {
5324  Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
5325  /*Map*/ diag::Severity::Ignored, Loc);
5326  }
5327  }
5328  ~DiagsUninitializedSeveretyRAII() {
5329  if (!IsIgnored)
5330  Diags.popMappings(SavedLoc);
5331  }
5332 };
5333 }
5334 
5336  SourceLocation StartLoc,
5337  SourceLocation LParenLoc,
5338  SourceLocation EndLoc) {
5340  SmallVector<Expr *, 8> PrivateCopies;
5342  bool IsImplicitClause =
5343  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
5344  auto ImplicitClauseLoc = DSAStack->getConstructLoc();
5345 
5346  for (auto &RefExpr : VarList) {
5347  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
5348  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5349  // It will be analyzed later.
5350  Vars.push_back(RefExpr);
5351  PrivateCopies.push_back(nullptr);
5352  Inits.push_back(nullptr);
5353  continue;
5354  }
5355 
5356  SourceLocation ELoc =
5357  IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc();
5358  // OpenMP [2.1, C/C++]
5359  // A list item is a variable name.
5360  // OpenMP [2.9.3.3, Restrictions, p.1]
5361  // A variable that is part of another variable (as an array or
5362  // structure element) cannot appear in a private clause.
5363  DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5364  if (!DE || !isa<VarDecl>(DE->getDecl())) {
5365  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
5366  continue;
5367  }
5368  Decl *D = DE->getDecl();
5369  VarDecl *VD = cast<VarDecl>(D);
5370 
5371  QualType Type = VD->getType();
5372  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
5373  // It will be analyzed later.
5374  Vars.push_back(DE);
5375  PrivateCopies.push_back(nullptr);
5376  Inits.push_back(nullptr);
5377  continue;
5378  }
5379 
5380  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
5381  // A variable that appears in a private clause must not have an incomplete
5382  // type or a reference type.
5383  if (RequireCompleteType(ELoc, Type,
5384  diag::err_omp_firstprivate_incomplete_type)) {
5385  continue;
5386  }
5387  if (Type->isReferenceType()) {
5388  if (IsImplicitClause) {
5389  Diag(ImplicitClauseLoc,
5390  diag::err_omp_task_predetermined_firstprivate_ref_type_arg)
5391  << Type;
5392  Diag(RefExpr->getExprLoc(), diag::note_used_here);
5393  } else {
5394  Diag(ELoc, diag::err_omp_clause_ref_type_arg)
5395  << getOpenMPClauseName(OMPC_firstprivate) << Type;
5396  }
5397  bool IsDecl =
5399  Diag(VD->getLocation(),
5400  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5401  << VD;
5402  continue;
5403  }
5404 
5405  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
5406  // A variable of class type (or array thereof) that appears in a private
5407  // clause requires an accessible, unambiguous copy constructor for the
5408  // class type.
5409  auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
5410 
5411  // If an implicit firstprivate variable found it was checked already.
5412  if (!IsImplicitClause) {
5413  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
5414  bool IsConstant = ElemType.isConstant(Context);
5415  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
5416  // A list item that specifies a given variable may not appear in more
5417  // than one clause on the same directive, except that a variable may be
5418  // specified in both firstprivate and lastprivate clauses.
5419  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
5420  DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
5421  Diag(ELoc, diag::err_omp_wrong_dsa)
5422  << getOpenMPClauseName(DVar.CKind)
5423  << getOpenMPClauseName(OMPC_firstprivate);
5424  ReportOriginalDSA(*this, DSAStack, VD, DVar);
5425  continue;
5426  }
5427 
5428  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
5429  // in a Construct]
5430  // Variables with the predetermined data-sharing attributes may not be
5431  // listed in data-sharing attributes clauses, except for the cases
5432  // listed below. For these exceptions only, listing a predetermined
5433  // variable in a data-sharing attribute clause is allowed and overrides
5434  // the variable's predetermined data-sharing attributes.
5435  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
5436  // in a Construct, C/C++, p.2]
5437  // Variables with const-qualified type having no mutable member may be
5438  // listed in a firstprivate clause, even if they are static data members.
5439  if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr &&
5440  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
5441  Diag(ELoc, diag::err_omp_wrong_dsa)
5442  << getOpenMPClauseName(DVar.CKind)
5443  << getOpenMPClauseName(OMPC_firstprivate);
5444  ReportOriginalDSA(*this, DSAStack, VD, DVar);
5445  continue;
5446  }
5447 
5448  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
5449  // OpenMP [2.9.3.4, Restrictions, p.2]
5450  // A list item that is private within a parallel region must not appear
5451  // in a firstprivate clause on a worksharing construct if any of the
5452  // worksharing regions arising from the worksharing construct ever bind
5453  // to any of the parallel regions arising from the parallel construct.
5454  if (isOpenMPWorksharingDirective(CurrDir) &&
5455  !isOpenMPParallelDirective(CurrDir)) {
5456  DVar = DSAStack->getImplicitDSA(VD, true);
5457  if (DVar.CKind != OMPC_shared &&
5458  (isOpenMPParallelDirective(DVar.DKind) ||
5459  DVar.DKind == OMPD_unknown)) {
5460  Diag(ELoc, diag::err_omp_required_access)
5461  << getOpenMPClauseName(OMPC_firstprivate)
5462  << getOpenMPClauseName(OMPC_shared);
5463  ReportOriginalDSA(*this, DSAStack, VD, DVar);
5464  continue;
5465  }
5466  }
5467  // OpenMP [2.9.3.4, Restrictions, p.3]
5468  // A list item that appears in a reduction clause of a parallel construct
5469  // must not appear in a firstprivate clause on a worksharing or task
5470  // construct if any of the worksharing or task regions arising from the
5471  // worksharing or task construct ever bind to any of the parallel regions
5472  // arising from the parallel construct.
5473  // OpenMP [2.9.3.4, Restrictions, p.4]
5474  // A list item that appears in a reduction clause in worksharing
5475  // construct must not appear in a firstprivate clause in a task construct
5476  // encountered during execution of any of the worksharing regions arising
5477  // from the worksharing construct.
5478  if (CurrDir == OMPD_task) {
5479  DVar =
5480  DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
5481  [](OpenMPDirectiveKind K) -> bool {
5482  return isOpenMPParallelDirective(K) ||
5484  },
5485  false);
5486  if (DVar.CKind == OMPC_reduction &&
5487  (isOpenMPParallelDirective(DVar.DKind) ||
5488  isOpenMPWorksharingDirective(DVar.DKind))) {
5489  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
5490  << getOpenMPDirectiveName(DVar.DKind);
5491  ReportOriginalDSA(*this, DSAStack, VD, DVar);
5492  continue;
5493  }
5494  }
5495  }
5496 
5497  // Variably modified types are not supported for tasks.
5498  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
5499  DSAStack->getCurrentDirective() == OMPD_task) {
5500  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
5501  << getOpenMPClauseName(OMPC_firstprivate) << Type
5502  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
5503  bool IsDecl =
5505  Diag(VD->getLocation(),
5506  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5507  << VD;
5508  continue;
5509  }
5510 
5511  Type = Type.getUnqualifiedType();
5512  auto VDPrivate = buildVarDecl(*this, ELoc, Type, VD->getName());
5513  // Generate helper private variable and initialize it with the value of the
5514  // original variable. The address of the original variable is replaced by
5515  // the address of the new private variable in the CodeGen. This new variable
5516  // is not added to IdResolver, so the code in the OpenMP region uses
5517  // original variable for proper diagnostics and variable capturing.
5518  Expr *VDInitRefExpr = nullptr;
5519  // For arrays generate initializer for single element and replace it by the
5520  // original array element in CodeGen.
5521  if (Type->isArrayType()) {
5522  auto VDInit =
5523  buildVarDecl(*this, DE->getExprLoc(), ElemType, VD->getName());
5524  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
5525  auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
5526  ElemType = ElemType.getUnqualifiedType();
5527  auto *VDInitTemp = buildVarDecl(*this, DE->getLocStart(), ElemType,
5528  ".firstprivate.temp");
5529  InitializedEntity Entity =
5532 
5533  InitializationSequence InitSeq(*this, Entity, Kind, Init);
5534  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
5535  if (Result.isInvalid())
5536  VDPrivate->setInvalidDecl();
5537  else
5538  VDPrivate->setInit(Result.getAs<Expr>());
5539  } else {
5540  auto *VDInit =
5541  buildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp");
5542  VDInitRefExpr =
5543  buildDeclRefExpr(*this, VDInit, DE->getType(), DE->getExprLoc());
5544  AddInitializerToDecl(VDPrivate,
5545  DefaultLvalueConversion(VDInitRefExpr).get(),
5546  /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
5547  }
5548  if (VDPrivate->isInvalidDecl()) {
5549  if (IsImplicitClause) {
5550  Diag(DE->getExprLoc(),
5551  diag::note_omp_task_predetermined_firstprivate_here);
5552  }
5553  continue;
5554  }
5555  CurContext->addDecl(VDPrivate);
5556  auto VDPrivateRefExpr = buildDeclRefExpr(
5557  *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc());
5558  DSAStack->addDSA(VD, DE, OMPC_firstprivate);
5559  Vars.push_back(DE);
5560  PrivateCopies.push_back(VDPrivateRefExpr);
5561  Inits.push_back(VDInitRefExpr);
5562  }
5563 
5564  if (Vars.empty())
5565  return nullptr;
5566 
5567  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
5568  Vars, PrivateCopies, Inits);
5569 }
5570 
5572  SourceLocation StartLoc,
5573  SourceLocation LParenLoc,
5574  SourceLocation EndLoc) {
5576  SmallVector<Expr *, 8> SrcExprs;
5577  SmallVector<Expr *, 8> DstExprs;
5578  SmallVector<Expr *, 8> AssignmentOps;
5579  for (auto &RefExpr : VarList) {
5580  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
5581  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5582  // It will be analyzed later.
5583  Vars.push_back(RefExpr);
5584  SrcExprs.push_back(nullptr);
5585  DstExprs.push_back(nullptr);
5586  AssignmentOps.push_back(nullptr);
5587  continue;
5588  }
5589 
5590  SourceLocation ELoc = RefExpr->getExprLoc();
5591  // OpenMP [2.1, C/C++]
5592  // A list item is a variable name.
5593  // OpenMP [2.14.3.5, Restrictions, p.1]
5594  // A variable that is part of another variable (as an array or structure
5595  // element) cannot appear in a lastprivate clause.
5596  DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5597  if (!DE || !isa<VarDecl>(DE->getDecl())) {
5598  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
5599  continue;
5600  }
5601  Decl *D = DE->getDecl();
5602  VarDecl *VD = cast<VarDecl>(D);
5603 
5604  QualType Type = VD->getType();
5605  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
5606  // It will be analyzed later.
5607  Vars.push_back(DE);
5608  SrcExprs.push_back(nullptr);
5609  DstExprs.push_back(nullptr);
5610  AssignmentOps.push_back(nullptr);
5611  continue;
5612  }
5613 
5614  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
5615  // A variable that appears in a lastprivate clause must not have an
5616  // incomplete type or a reference type.
5617  if (RequireCompleteType(ELoc, Type,
5618  diag::err_omp_lastprivate_incomplete_type)) {
5619  continue;
5620  }
5621  if (Type->isReferenceType()) {
5622  Diag(ELoc, diag::err_omp_clause_ref_type_arg)
5623  << getOpenMPClauseName(OMPC_lastprivate) << Type;
5624  bool IsDecl =
5626  Diag(VD->getLocation(),
5627  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5628  << VD;
5629  continue;
5630  }
5631 
5632  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
5633  // in a Construct]
5634  // Variables with the predetermined data-sharing attributes may not be
5635  // listed in data-sharing attributes clauses, except for the cases
5636  // listed below.
5637  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
5638  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
5639  DVar.CKind != OMPC_firstprivate &&
5640  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
5641  Diag(ELoc, diag::err_omp_wrong_dsa)
5642  << getOpenMPClauseName(DVar.CKind)
5643  << getOpenMPClauseName(OMPC_lastprivate);
5644  ReportOriginalDSA(*this, DSAStack, VD, DVar);
5645  continue;
5646  }
5647 
5648  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
5649  // OpenMP [2.14.3.5, Restrictions, p.2]
5650  // A list item that is private within a parallel region, or that appears in
5651  // the reduction clause of a parallel construct, must not appear in a
5652  // lastprivate clause on a worksharing construct if any of the corresponding
5653  // worksharing regions ever binds to any of the corresponding parallel
5654  // regions.
5655  DSAStackTy::DSAVarData TopDVar = DVar;
5656  if (isOpenMPWorksharingDirective(CurrDir) &&
5657  !isOpenMPParallelDirective(CurrDir)) {
5658  DVar = DSAStack->getImplicitDSA(VD, true);
5659  if (DVar.CKind != OMPC_shared) {
5660  Diag(ELoc, diag::err_omp_required_access)
5661  << getOpenMPClauseName(OMPC_lastprivate)
5662  << getOpenMPClauseName(OMPC_shared);
5663  ReportOriginalDSA(*this, DSAStack, VD, DVar);
5664  continue;
5665  }
5666  }
5667  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
5668  // A variable of class type (or array thereof) that appears in a
5669  // lastprivate clause requires an accessible, unambiguous default
5670  // constructor for the class type, unless the list item is also specified
5671  // in a firstprivate clause.
5672  // A variable of class type (or array thereof) that appears in a
5673  // lastprivate clause requires an accessible, unambiguous copy assignment
5674  // operator for the class type.
5676  auto *SrcVD = buildVarDecl(*this, DE->getLocStart(),
5677  Type.getUnqualifiedType(), ".lastprivate.src");
5678  auto *PseudoSrcExpr = buildDeclRefExpr(
5679  *this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc());
5680  auto *DstVD =
5681  buildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst");
5682  auto *PseudoDstExpr =
5683  buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
5684  // For arrays generate assignment operation for single element and replace
5685  // it by the original array element in CodeGen.
5686  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
5687  PseudoDstExpr, PseudoSrcExpr);
5688  if (AssignmentOp.isInvalid())
5689  continue;
5690  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
5691  /*DiscardedValue=*/true);
5692  if (AssignmentOp.isInvalid())
5693  continue;
5694 
5695  if (TopDVar.CKind != OMPC_firstprivate)
5696  DSAStack->addDSA(VD, DE, OMPC_lastprivate);
5697  Vars.push_back(DE);
5698  SrcExprs.push_back(PseudoSrcExpr);
5699  DstExprs.push_back(PseudoDstExpr);
5700  AssignmentOps.push_back(AssignmentOp.get());
5701  }
5702 
5703  if (Vars.empty())
5704  return nullptr;
5705 
5706  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
5707  Vars, SrcExprs, DstExprs, AssignmentOps);
5708 }
5709 
5711  SourceLocation StartLoc,
5712  SourceLocation LParenLoc,
5713  SourceLocation EndLoc) {
5715  for (auto &RefExpr : VarList) {
5716  assert(RefExpr && "NULL expr in OpenMP shared clause.");
5717  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5718  // It will be analyzed later.
5719  Vars.push_back(RefExpr);
5720  continue;
5721  }
5722 
5723  SourceLocation ELoc = RefExpr->getExprLoc();
5724  // OpenMP [2.1, C/C++]
5725  // A list item is a variable name.
5726  // OpenMP [2.14.3.2, Restrictions, p.1]
5727  // A variable that is part of another variable (as an array or structure
5728  // element) cannot appear in a shared unless it is a static data member
5729  // of a C++ class.
5730  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
5731  if (!DE || !isa<VarDecl>(DE->getDecl())) {
5732  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
5733  continue;
5734  }
5735  Decl *D = DE->getDecl();
5736  VarDecl *VD = cast<VarDecl>(D);
5737 
5738  QualType Type = VD->getType();
5739  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
5740  // It will be analyzed later.
5741  Vars.push_back(DE);
5742  continue;
5743  }
5744 
5745  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
5746  // in a Construct]
5747  // Variables with the predetermined data-sharing attributes may not be
5748  // listed in data-sharing attributes clauses, except for the cases
5749  // listed below. For these exceptions only, listing a predetermined
5750  // variable in a data-sharing attribute clause is allowed and overrides
5751  // the variable's predetermined data-sharing attributes.
5752  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
5753  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
5754  DVar.RefExpr) {
5755  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
5756  << getOpenMPClauseName(OMPC_shared);
5757  ReportOriginalDSA(*this, DSAStack, VD, DVar);
5758  continue;
5759  }
5760 
5761  DSAStack->addDSA(VD, DE, OMPC_shared);
5762  Vars.push_back(DE);
5763  }
5764 
5765  if (Vars.empty())
5766  return nullptr;
5767 
5768  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
5769 }
5770 
5771 namespace {
5772 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
5773  DSAStackTy *Stack;
5774 
5775 public:
5776  bool VisitDeclRefExpr(DeclRefExpr *E) {
5777  if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
5778  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false);
5779  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
5780  return false;
5781  if (DVar.CKind != OMPC_unknown)
5782  return true;
5783  DSAStackTy::DSAVarData DVarPrivate =
5784  Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false);
5785  if (DVarPrivate.CKind != OMPC_unknown)
5786  return true;
5787  return false;
5788  }
5789  return false;
5790  }
5791  bool VisitStmt(Stmt *S) {
5792  for (auto Child : S->children()) {
5793  if (Child && Visit(Child))
5794  return true;
5795  }
5796  return false;
5797  }
5798  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
5799 };
5800 } // namespace
5801 
5803  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
5805  CXXScopeSpec &ReductionIdScopeSpec,
5806  const DeclarationNameInfo &ReductionId) {
5807  // TODO: Allow scope specification search when 'declare reduction' is
5808  // supported.
5809  assert(ReductionIdScopeSpec.isEmpty() &&
5810  "No support for scoped reduction identifiers yet.");
5811 
5812  auto DN = ReductionId.getName();
5813  auto OOK = DN.getCXXOverloadedOperator();
5815 
5816  // OpenMP [2.14.3.6, reduction clause]
5817  // C
5818  // reduction-identifier is either an identifier or one of the following
5819  // operators: +, -, *, &, |, ^, && and ||
5820  // C++
5821  // reduction-identifier is either an id-expression or one of the following
5822  // operators: +, -, *, &, |, ^, && and ||
5823  // FIXME: Only 'min' and 'max' identifiers are supported for now.
5824  switch (OOK) {
5825  case OO_Plus:
5826  case OO_Minus:
5827  BOK = BO_Add;
5828  break;
5829  case OO_Star:
5830  BOK = BO_Mul;
5831  break;
5832  case OO_Amp:
5833  BOK = BO_And;
5834  break;
5835  case OO_Pipe:
5836  BOK = BO_Or;
5837  break;
5838  case OO_Caret:
5839  BOK = BO_Xor;
5840  break;
5841  case OO_AmpAmp:
5842  BOK = BO_LAnd;
5843  break;
5844  case OO_PipePipe:
5845  BOK = BO_LOr;
5846  break;
5847  case OO_New:
5848  case OO_Delete:
5849  case OO_Array_New:
5850  case OO_Array_Delete:
5851  case OO_Slash:
5852  case OO_Percent:
5853  case OO_Tilde:
5854  case OO_Exclaim:
5855  case OO_Equal:
5856  case OO_Less:
5857  case OO_Greater:
5858  case OO_LessEqual:
5859  case OO_GreaterEqual:
5860  case OO_PlusEqual:
5861  case OO_MinusEqual:
5862  case OO_StarEqual:
5863  case OO_SlashEqual:
5864  case OO_PercentEqual:
5865  case OO_CaretEqual:
5866  case OO_AmpEqual:
5867  case OO_PipeEqual:
5868  case OO_LessLess:
5869  case OO_GreaterGreater:
5870  case OO_LessLessEqual:
5871  case OO_GreaterGreaterEqual:
5872  case OO_EqualEqual:
5873  case OO_ExclaimEqual:
5874  case OO_PlusPlus:
5875  case OO_MinusMinus:
5876  case OO_Comma:
5877  case OO_ArrowStar:
5878  case OO_Arrow:
5879  case OO_Call:
5880  case OO_Subscript:
5881  case OO_Conditional:
5883  llvm_unreachable("Unexpected reduction identifier");
5884  case OO_None:
5885  if (auto II = DN.getAsIdentifierInfo()) {
5886  if (II->isStr("max"))
5887  BOK = BO_GT;
5888  else if (II->isStr("min"))
5889  BOK = BO_LT;
5890  }
5891  break;
5892  }
5893  SourceRange ReductionIdRange;
5894  if (ReductionIdScopeSpec.isValid()) {
5895  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
5896  }
5897  ReductionIdRange.setEnd(ReductionId.getEndLoc());
5898  if (BOK == BO_Comma) {
5899  // Not allowed reduction identifier is found.
5900  Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier)
5901  << ReductionIdRange;
5902  return nullptr;
5903  }
5904 
5908  SmallVector<Expr *, 8> ReductionOps;
5909  for (auto RefExpr : VarList) {
5910  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
5911  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5912  // It will be analyzed later.
5913  Vars.push_back(RefExpr);
5914  LHSs.push_back(nullptr);
5915  RHSs.push_back(nullptr);
5916  ReductionOps.push_back(nullptr);
5917  continue;
5918  }
5919 
5920  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5921  RefExpr->isInstantiationDependent() ||
5922  RefExpr->containsUnexpandedParameterPack()) {
5923  // It will be analyzed later.
5924  Vars.push_back(RefExpr);
5925  LHSs.push_back(nullptr);
5926  RHSs.push_back(nullptr);
5927  ReductionOps.push_back(nullptr);
5928  continue;
5929  }
5930 
5931  auto ELoc = RefExpr->getExprLoc();
5932  auto ERange = RefExpr->getSourceRange();
5933  // OpenMP [2.1, C/C++]
5934  // A list item is a variable or array section, subject to the restrictions
5935  // specified in Section 2.4 on page 42 and in each of the sections
5936  // describing clauses and directives for which a list appears.
5937  // OpenMP [2.14.3.3, Restrictions, p.1]
5938  // A variable that is part of another variable (as an array or
5939  // structure element) cannot appear in a private clause.
5940  auto DE = dyn_cast<DeclRefExpr>(RefExpr);
5941  if (!DE || !isa<VarDecl>(DE->getDecl())) {
5942  Diag(ELoc, diag::err_omp_expected_var_name) << ERange;
5943  continue;
5944  }
5945  auto D = DE->getDecl();
5946  auto VD = cast<VarDecl>(D);
5947  auto Type = VD->getType();
5948  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
5949  // A variable that appears in a private clause must not have an incomplete
5950  // type or a reference type.
5951  if (RequireCompleteType(ELoc, Type,
5952  diag::err_omp_reduction_incomplete_type))
5953  continue;
5954  // OpenMP [2.14.3.6, reduction clause, Restrictions]
5955  // Arrays may not appear in a reduction clause.
5956  if (Type.getNonReferenceType()->isArrayType()) {
5957  Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange;
5958  bool IsDecl =
5959  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
5960  Diag(VD->getLocation(),
5961  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5962  << VD;
5963  continue;
5964  }
5965  // OpenMP [2.14.3.6, reduction clause, Restrictions]
5966  // A list item that appears in a reduction clause must not be
5967  // const-qualified.
5968  if (Type.getNonReferenceType().isConstant(Context)) {
5969  Diag(ELoc, diag::err_omp_const_variable)
5970  << getOpenMPClauseName(OMPC_reduction) << Type << ERange;
5971  bool IsDecl =
5972  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
5973  Diag(VD->getLocation(),
5974  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5975  << VD;
5976  continue;
5977  }
5978  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
5979  // If a list-item is a reference type then it must bind to the same object
5980  // for all threads of the team.
5981  VarDecl *VDDef = VD->getDefinition();
5982  if (Type->isReferenceType() && VDDef) {
5983  DSARefChecker Check(DSAStack);
5984  if (Check.Visit(VDDef->getInit())) {
5985  Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
5986  Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
5987  continue;
5988  }
5989  }
5990  // OpenMP [2.14.3.6, reduction clause, Restrictions]
5991  // The type of a list item that appears in a reduction clause must be valid
5992  // for the reduction-identifier. For a max or min reduction in C, the type
5993  // of the list item must be an allowed arithmetic data type: char, int,
5994  // float, double, or _Bool, possibly modified with long, short, signed, or
5995  // unsigned. For a max or min reduction in C++, the type of the list item
5996  // must be an allowed arithmetic data type: char, wchar_t, int, float,
5997  // double, or bool, possibly modified with long, short, signed, or unsigned.
5998  if ((BOK == BO_GT || BOK == BO_LT) &&
5999  !(Type->isScalarType() ||
6000  (getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
6001  Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
6002  << getLangOpts().CPlusPlus;
6003  bool IsDecl =
6004  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
6005  Diag(VD->getLocation(),
6006  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6007  << VD;
6008  continue;
6009  }
6010  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
6011  !getLangOpts().CPlusPlus && Type->isFloatingType()) {
6012  Diag(ELoc, diag::err_omp_clause_floating_type_arg);
6013  bool IsDecl =
6014  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
6015  Diag(VD->getLocation(),
6016  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6017  << VD;
6018  continue;
6019  }
6020  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
6021  // in a Construct]
6022  // Variables with the predetermined data-sharing attributes may not be
6023  // listed in data-sharing attributes clauses, except for the cases
6024  // listed below. For these exceptions only, listing a predetermined
6025  // variable in a data-sharing attribute clause is allowed and overrides
6026  // the variable's predetermined data-sharing attributes.
6027  // OpenMP [2.14.3.6, Restrictions, p.3]
6028  // Any number of reduction clauses can be specified on the directive,
6029  // but a list item can appear only once in the reduction clauses for that
6030  // directive.
6031  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
6032  if (DVar.CKind == OMPC_reduction) {
6033  Diag(ELoc, diag::err_omp_once_referenced)
6034  << getOpenMPClauseName(OMPC_reduction);
6035  if (DVar.RefExpr) {
6036  Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
6037  }
6038  } else if (DVar.CKind != OMPC_unknown) {
6039  Diag(ELoc, diag::err_omp_wrong_dsa)
6040  << getOpenMPClauseName(DVar.CKind)
6041  << getOpenMPClauseName(OMPC_reduction);
6042  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6043  continue;
6044  }
6045 
6046  // OpenMP [2.14.3.6, Restrictions, p.1]
6047  // A list item that appears in a reduction clause of a worksharing
6048  // construct must be shared in the parallel regions to which any of the
6049  // worksharing regions arising from the worksharing construct bind.
6050  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
6051  if (isOpenMPWorksharingDirective(CurrDir) &&
6052  !isOpenMPParallelDirective(CurrDir)) {
6053  DVar = DSAStack->getImplicitDSA(VD, true);
6054  if (DVar.CKind != OMPC_shared) {
6055  Diag(ELoc, diag::err_omp_required_access)
6056  << getOpenMPClauseName(OMPC_reduction)
6057  << getOpenMPClauseName(OMPC_shared);
6058  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6059  continue;
6060  }
6061  }
6062  Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
6063  auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs");
6064  auto *RHSVD = buildVarDecl(*this, ELoc, Type, VD->getName());
6065  // Add initializer for private variable.
6066  Expr *Init = nullptr;
6067  switch (BOK) {
6068  case BO_Add:
6069  case BO_Xor:
6070  case BO_Or:
6071  case BO_LOr:
6072  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
6073  if (Type->isScalarType() || Type->isAnyComplexType()) {
6074  Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get();
6075  }
6076  break;
6077  case BO_Mul:
6078  case BO_LAnd:
6079  if (Type->isScalarType() || Type->isAnyComplexType()) {
6080  // '*' and '&&' reduction ops - initializer is '1'.
6081  Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get();
6082  }
6083  break;
6084  case BO_And: {
6085  // '&' reduction op - initializer is '~0'.
6086  QualType OrigType = Type;
6087  if (auto *ComplexTy = OrigType->getAs<ComplexType>()) {
6088  Type = ComplexTy->getElementType();
6089  }
6090  if (Type->isRealFloatingType()) {
6091  llvm::APFloat InitValue =
6092  llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
6093  /*isIEEE=*/true);
6094  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
6095  Type, ELoc);
6096  } else if (Type->isScalarType()) {
6097  auto Size = Context.getTypeSize(Type);
6098  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
6099  llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
6100  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
6101  }
6102  if (Init && OrigType->isAnyComplexType()) {
6103  // Init = 0xFFFF + 0xFFFFi;
6104  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
6105  Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
6106  }
6107  Type = OrigType;
6108  break;
6109  }
6110  case BO_LT:
6111  case BO_GT: {
6112  // 'min' reduction op - initializer is 'Largest representable number in
6113  // the reduction list item type'.
6114  // 'max' reduction op - initializer is 'Least representable number in
6115  // the reduction list item type'.
6116  if (Type->isIntegerType() || Type->isPointerType()) {
6117  bool IsSigned = Type->hasSignedIntegerRepresentation();
6118  auto Size = Context.getTypeSize(Type);
6119  QualType IntTy =
6120  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
6121  llvm::APInt InitValue =
6122  (BOK != BO_LT)
6123  ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
6124  : llvm::APInt::getMinValue(Size)
6125  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
6126  : llvm::APInt::getMaxValue(Size);
6127  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
6128  if (Type->isPointerType()) {
6129  // Cast to pointer type.
6132  SourceLocation(), Init);
6133  if (CastExpr.isInvalid())
6134  continue;
6135  Init = CastExpr.get();
6136  }
6137  } else if (Type->isRealFloatingType()) {
6138  llvm::APFloat InitValue = llvm::APFloat::getLargest(
6139  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
6140  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
6141  Type, ELoc);
6142  }
6143  break;
6144  }
6145  case BO_PtrMemD:
6146  case BO_PtrMemI:
6147  case BO_MulAssign:
6148  case BO_Div:
6149  case BO_Rem:
6150  case BO_Sub:
6151  case BO_Shl:
6152  case BO_Shr:
6153  case BO_LE:
6154  case BO_GE:
6155  case BO_EQ:
6156  case BO_NE:
6157  case BO_AndAssign:
6158  case BO_XorAssign:
6159  case BO_OrAssign:
6160  case BO_Assign:
6161  case BO_AddAssign:
6162  case BO_SubAssign:
6163  case BO_DivAssign:
6164  case BO_RemAssign:
6165  case BO_ShlAssign:
6166  case BO_ShrAssign:
6167  case BO_Comma:
6168  llvm_unreachable("Unexpected reduction operation");
6169  }
6170  if (Init) {
6171  AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false,
6172  /*TypeMayContainAuto=*/false);
6173  } else {
6174  ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false);
6175  }
6176  if (!RHSVD->hasInit()) {
6177  Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
6178  << ReductionIdRange;
6179  bool IsDecl =
6180  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
6181  Diag(VD->getLocation(),
6182  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6183  << VD;
6184  continue;
6185  }
6186  auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc);
6187  auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc);
6188  ExprResult ReductionOp =
6189  BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK,
6190  LHSDRE, RHSDRE);
6191  if (ReductionOp.isUsable()) {
6192  if (BOK != BO_LT && BOK != BO_GT) {
6193  ReductionOp =
6194  BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
6195  BO_Assign, LHSDRE, ReductionOp.get());
6196  } else {
6197  auto *ConditionalOp = new (Context) ConditionalOperator(
6198  ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(),
6199  RHSDRE, Type, VK_LValue, OK_Ordinary);
6200  ReductionOp =
6201  BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
6202  BO_Assign, LHSDRE, ConditionalOp);
6203  }
6204  if (ReductionOp.isUsable()) {
6205  ReductionOp = ActOnFinishFullExpr(ReductionOp.get());
6206  }
6207  }
6208  if (ReductionOp.isInvalid())
6209  continue;
6210 
6211  DSAStack->addDSA(VD, DE, OMPC_reduction);
6212  Vars.push_back(DE);
6213  LHSs.push_back(LHSDRE);
6214  RHSs.push_back(RHSDRE);
6215  ReductionOps.push_back(ReductionOp.get());
6216  }
6217 
6218  if (Vars.empty())
6219  return nullptr;
6220 
6222  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
6223  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, LHSs,
6224  RHSs, ReductionOps);
6225 }
6226 
6228  SourceLocation StartLoc,
6229  SourceLocation LParenLoc,
6231  SourceLocation EndLoc) {
6234  for (auto &RefExpr : VarList) {
6235  assert(RefExpr && "NULL expr in OpenMP linear clause.");
6236  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6237  // It will be analyzed later.
6238  Vars.push_back(RefExpr);
6239  Inits.push_back(nullptr);
6240  continue;
6241  }
6242 
6243  // OpenMP [2.14.3.7, linear clause]
6244  // A list item that appears in a linear clause is subject to the private
6245  // clause semantics described in Section 2.14.3.3 on page 159 except as
6246  // noted. In addition, the value of the new list item on each iteration
6247  // of the associated loop(s) corresponds to the value of the original
6248  // list item before entering the construct plus the logical number of
6249  // the iteration times linear-step.
6250 
6251  SourceLocation ELoc = RefExpr->getExprLoc();
6252  // OpenMP [2.1, C/C++]
6253  // A list item is a variable name.
6254  // OpenMP [2.14.3.3, Restrictions, p.1]
6255  // A variable that is part of another variable (as an array or
6256  // structure element) cannot appear in a private clause.
6257  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
6258  if (!DE || !isa<VarDecl>(DE->getDecl())) {
6259  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6260  continue;
6261  }
6262 
6263  VarDecl *VD = cast<VarDecl>(DE->getDecl());
6264 
6265  // OpenMP [2.14.3.7, linear clause]
6266  // A list-item cannot appear in more than one linear clause.
6267  // A list-item that appears in a linear clause cannot appear in any
6268  // other data-sharing attribute clause.
6269  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
6270  if (DVar.RefExpr) {
6271  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
6272  << getOpenMPClauseName(OMPC_linear);
6273  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6274  continue;
6275  }
6276 
6277  QualType QType = VD->getType();
6278  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
6279  // It will be analyzed later.
6280  Vars.push_back(DE);
6281  Inits.push_back(nullptr);
6282  continue;
6283  }
6284 
6285  // A variable must not have an incomplete type or a reference type.
6286  if (RequireCompleteType(ELoc, QType,
6287  diag::err_omp_linear_incomplete_type)) {
6288  continue;
6289  }
6290  if (QType->isReferenceType()) {
6291  Diag(ELoc, diag::err_omp_clause_ref_type_arg)
6292  << getOpenMPClauseName(OMPC_linear) << QType;
6293  bool IsDecl =
6295  Diag(VD->getLocation(),
6296  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6297  << VD;
6298  continue;
6299  }
6300 
6301  // A list item must not be const-qualified.
6302  if (QType.isConstant(Context)) {
6303  Diag(ELoc, diag::err_omp_const_variable)
6304  << getOpenMPClauseName(OMPC_linear);
6305  bool IsDecl =
6307  Diag(VD->getLocation(),
6308  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6309  << VD;
6310  continue;
6311  }
6312 
6313  // A list item must be of integral or pointer type.
6314  QType = QType.getUnqualifiedType().getCanonicalType();
6315  const Type *Ty = QType.getTypePtrOrNull();
6316  if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
6317  !Ty->isPointerType())) {
6318  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType;
6319  bool IsDecl =
6321  Diag(VD->getLocation(),
6322  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6323  << VD;
6324  continue;
6325  }
6326 
6327  // Build var to save initial value.
6328  VarDecl *Init = buildVarDecl(*this, ELoc, QType, ".linear.start");
6330  /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
6331  auto InitRef = buildDeclRefExpr(
6332  *this, Init, DE->getType().getUnqualifiedType(), DE->getExprLoc());
6333  DSAStack->addDSA(VD, DE, OMPC_linear);
6334  Vars.push_back(DE);
6335  Inits.push_back(InitRef);
6336  }
6337 
6338  if (Vars.empty())
6339  return nullptr;
6340 
6341  Expr *StepExpr = Step;
6342  Expr *CalcStepExpr = nullptr;
6343  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6344  !Step->isInstantiationDependent() &&
6346  SourceLocation StepLoc = Step->getLocStart();
6348  if (Val.isInvalid())
6349  return nullptr;
6350  StepExpr = Val.get();
6351 
6352  // Build var to save the step value.
6353  VarDecl *SaveVar =
6354  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
6355  ExprResult SaveRef =
6356  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
6358  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
6359 
6360  // Warn about zero linear step (it would be probably better specified as
6361  // making corresponding variables 'const').
6362  llvm::APSInt Result;
6363  bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
6364  if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
6365  Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
6366  << (Vars.size() > 1);
6367  if (!IsConstant && CalcStep.isUsable()) {
6368  // Calculate the step beforehand instead of doing this on each iteration.
6369  // (This is not used if the number of iterations may be kfold-ed).
6370  CalcStepExpr = CalcStep.get();
6371  }
6372  }
6373 
6374  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, ColonLoc, EndLoc,
6375  Vars, Inits, StepExpr, CalcStepExpr);
6376 }
6377 
6379  Expr *NumIterations, Sema &SemaRef,
6380  Scope *S) {
6381  // Walk the vars and build update/final expressions for the CodeGen.
6384  Expr *Step = Clause.getStep();
6385  Expr *CalcStep = Clause.getCalcStep();
6386  // OpenMP [2.14.3.7, linear clause]
6387  // If linear-step is not specified it is assumed to be 1.
6388  if (Step == nullptr)
6389  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
6390  else if (CalcStep)
6391  Step = cast<BinaryOperator>(CalcStep)->getLHS();
6392  bool HasErrors = false;
6393  auto CurInit = Clause.inits().begin();
6394  for (auto &RefExpr : Clause.varlists()) {
6395  Expr *InitExpr = *CurInit;
6396 
6397  // Build privatized reference to the current linear var.
6398  auto DE = cast<DeclRefExpr>(RefExpr);
6399  auto PrivateRef =
6400  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
6401  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
6402  /*RefersToCapture=*/true);
6403 
6404  // Build update: Var = InitExpr + IV * Step
6405  ExprResult Update =
6406  BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), PrivateRef,
6407  InitExpr, IV, Step, /* Subtract */ false);
6408  Update = SemaRef.ActOnFinishFullExpr(Update.get());
6409 
6410  // Build final: Var = InitExpr + NumIterations * Step
6411  ExprResult Final =
6412  BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), PrivateRef,
6413  InitExpr, NumIterations, Step, /* Subtract */ false);
6414  Final = SemaRef.ActOnFinishFullExpr(Final.get());
6415  if (!Update.isUsable() || !Final.isUsable()) {
6416  Updates.push_back(nullptr);
6417  Finals.push_back(nullptr);
6418  HasErrors = true;
6419  } else {
6420  Updates.push_back(Update.get());
6421  Finals.push_back(Final.get());
6422  }
6423  ++CurInit;
6424  }
6425  Clause.setUpdates(Updates);
6426  Clause.setFinals(Finals);
6427  return HasErrors;
6428 }
6429 
6431  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
6433 
6435  for (auto &RefExpr : VarList) {
6436  assert(RefExpr && "NULL expr in OpenMP aligned clause.");
6437  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6438  // It will be analyzed later.
6439  Vars.push_back(RefExpr);
6440  continue;
6441  }
6442 
6443  SourceLocation ELoc = RefExpr->getExprLoc();
6444  // OpenMP [2.1, C/C++]
6445  // A list item is a variable name.
6446  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
6447  if (!DE || !isa<VarDecl>(DE->getDecl())) {
6448  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6449  continue;
6450  }
6451 
6452  VarDecl *VD = cast<VarDecl>(DE->getDecl());
6453 
6454  // OpenMP [2.8.1, simd construct, Restrictions]
6455  // The type of list items appearing in the aligned clause must be
6456  // array, pointer, reference to array, or reference to pointer.
6457  QualType QType = VD->getType();
6459  const Type *Ty = QType.getTypePtrOrNull();
6460  if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() &&
6461  !Ty->isPointerType())) {
6462  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
6463  << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange();
6464  bool IsDecl =
6466  Diag(VD->getLocation(),
6467  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6468  << VD;
6469  continue;
6470  }
6471 
6472  // OpenMP [2.8.1, simd construct, Restrictions]
6473  // A list-item cannot appear in more than one aligned clause.
6474  if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) {
6475  Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
6476  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
6477  << getOpenMPClauseName(OMPC_aligned);
6478  continue;
6479  }
6480 
6481  Vars.push_back(DE);
6482  }
6483 
6484  // OpenMP [2.8.1, simd construct, Description]
6485  // The parameter of the aligned clause, alignment, must be a constant
6486  // positive integer expression.
6487  // If no optional parameter is specified, implementation-defined default
6488  // alignments for SIMD instructions on the target platforms are assumed.
6489  if (Alignment != nullptr) {
6490  ExprResult AlignResult =
6491  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
6492  if (AlignResult.isInvalid())
6493  return nullptr;
6494  Alignment = AlignResult.get();
6495  }
6496  if (Vars.empty())
6497  return nullptr;
6498 
6499  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
6500  EndLoc, Vars, Alignment);
6501 }
6502 
6504  SourceLocation StartLoc,
6505  SourceLocation LParenLoc,
6506  SourceLocation EndLoc) {
6508  SmallVector<Expr *, 8> SrcExprs;
6509  SmallVector<Expr *, 8> DstExprs;
6510  SmallVector<Expr *, 8> AssignmentOps;
6511  for (auto &RefExpr : VarList) {
6512  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
6513  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6514  // It will be analyzed later.
6515  Vars.push_back(RefExpr);
6516  SrcExprs.push_back(nullptr);
6517  DstExprs.push_back(nullptr);
6518  AssignmentOps.push_back(nullptr);
6519  continue;
6520  }
6521 
6522  SourceLocation ELoc = RefExpr->getExprLoc();
6523  // OpenMP [2.1, C/C++]
6524  // A list item is a variable name.
6525  // OpenMP [2.14.4.1, Restrictions, p.1]
6526  // A list item that appears in a copyin clause must be threadprivate.
6527  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
6528  if (!DE || !isa<VarDecl>(DE->getDecl())) {
6529  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6530  continue;
6531  }
6532 
6533  Decl *D = DE->getDecl();
6534  VarDecl *VD = cast<VarDecl>(D);
6535 
6536  QualType Type = VD->getType();
6537  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6538  // It will be analyzed later.
6539  Vars.push_back(DE);
6540  SrcExprs.push_back(nullptr);
6541  DstExprs.push_back(nullptr);
6542  AssignmentOps.push_back(nullptr);
6543  continue;
6544  }
6545 
6546  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
6547  // A list item that appears in a copyin clause must be threadprivate.
6548  if (!DSAStack->isThreadPrivate(VD)) {
6549  Diag(ELoc, diag::err_omp_required_access)
6550  << getOpenMPClauseName(OMPC_copyin)
6551  << getOpenMPDirectiveName(OMPD_threadprivate);
6552  continue;
6553  }
6554 
6555  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
6556  // A variable of class type (or array thereof) that appears in a
6557  // copyin clause requires an accessible, unambiguous copy assignment
6558  // operator for the class type.
6559  auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
6560  auto *SrcVD = buildVarDecl(*this, DE->getLocStart(),
6561  ElemType.getUnqualifiedType(), ".copyin.src");
6562  auto *PseudoSrcExpr = buildDeclRefExpr(
6563  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
6564  auto *DstVD =
6565  buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst");
6566  auto *PseudoDstExpr =
6567  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
6568  // For arrays generate assignment operation for single element and replace
6569  // it by the original array element in CodeGen.
6570  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
6571  PseudoDstExpr, PseudoSrcExpr);
6572  if (AssignmentOp.isInvalid())
6573  continue;
6574  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
6575  /*DiscardedValue=*/true);
6576  if (AssignmentOp.isInvalid())
6577  continue;
6578 
6579  DSAStack->addDSA(VD, DE, OMPC_copyin);
6580  Vars.push_back(DE);
6581  SrcExprs.push_back(PseudoSrcExpr);
6582  DstExprs.push_back(PseudoDstExpr);
6583  AssignmentOps.push_back(AssignmentOp.get());
6584  }
6585 
6586  if (Vars.empty())
6587  return nullptr;
6588 
6589  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
6590  SrcExprs, DstExprs, AssignmentOps);
6591 }
6592 
6594  SourceLocation StartLoc,
6595  SourceLocation LParenLoc,
6596  SourceLocation EndLoc) {
6598  SmallVector<Expr *, 8> SrcExprs;
6599  SmallVector<Expr *, 8> DstExprs;
6600  SmallVector<Expr *, 8> AssignmentOps;
6601  for (auto &RefExpr : VarList) {
6602  assert(RefExpr && "NULL expr in OpenMP copyprivate clause.");
6603  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6604  // It will be analyzed later.
6605  Vars.push_back(RefExpr);
6606  SrcExprs.push_back(nullptr);
6607  DstExprs.push_back(nullptr);
6608  AssignmentOps.push_back(nullptr);
6609  continue;
6610  }
6611 
6612  SourceLocation ELoc = RefExpr->getExprLoc();
6613  // OpenMP [2.1, C/C++]
6614  // A list item is a variable name.
6615  // OpenMP [2.14.4.1, Restrictions, p.1]
6616  // A list item that appears in a copyin clause must be threadprivate.
6617  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
6618  if (!DE || !isa<VarDecl>(DE->getDecl())) {
6619  Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6620  continue;
6621  }
6622 
6623  Decl *D = DE->getDecl();
6624  VarDecl *VD = cast<VarDecl>(D);
6625 
6626  QualType Type = VD->getType();
6627  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6628  // It will be analyzed later.
6629  Vars.push_back(DE);
6630  SrcExprs.push_back(nullptr);
6631  DstExprs.push_back(nullptr);
6632  AssignmentOps.push_back(nullptr);
6633  continue;
6634  }
6635 
6636  // OpenMP [2.14.4.2, Restrictions, p.2]
6637  // A list item that appears in a copyprivate clause may not appear in a
6638  // private or firstprivate clause on the single construct.
6639  if (!DSAStack->isThreadPrivate(VD)) {
6640  auto DVar = DSAStack->getTopDSA(VD, false);
6641  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
6642  DVar.RefExpr) {
6643  Diag(ELoc, diag::err_omp_wrong_dsa)
6644  << getOpenMPClauseName(DVar.CKind)
6645  << getOpenMPClauseName(OMPC_copyprivate);
6646  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6647  continue;
6648  }
6649 
6650  // OpenMP [2.11.4.2, Restrictions, p.1]
6651  // All list items that appear in a copyprivate clause must be either
6652  // threadprivate or private in the enclosing context.
6653  if (DVar.CKind == OMPC_unknown) {
6654  DVar = DSAStack->getImplicitDSA(VD, false);
6655  if (DVar.CKind == OMPC_shared) {
6656  Diag(ELoc, diag::err_omp_required_access)
6657  << getOpenMPClauseName(OMPC_copyprivate)
6658  << "threadprivate or private in the enclosing context";
6659  ReportOriginalDSA(*this, DSAStack, VD, DVar);
6660  continue;
6661  }
6662  }
6663  }
6664 
6665  // Variably modified types are not supported.
6666  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
6667  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
6668  << getOpenMPClauseName(OMPC_copyprivate) << Type
6669  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
6670  bool IsDecl =
6672  Diag(VD->getLocation(),
6673  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6674  << VD;
6675  continue;
6676  }
6677 
6678  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
6679  // A variable of class type (or array thereof) that appears in a
6680  // copyin clause requires an accessible, unambiguous copy assignment
6681  // operator for the class type.
6683  auto *SrcVD =
6684  buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src");
6685  auto *PseudoSrcExpr =
6686  buildDeclRefExpr(*this, SrcVD, Type, DE->getExprLoc());
6687  auto *DstVD =
6688  buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst");
6689  auto *PseudoDstExpr =
6690  buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
6691  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
6692  PseudoDstExpr, PseudoSrcExpr);
6693  if (AssignmentOp.isInvalid())
6694  continue;
6695  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
6696  /*DiscardedValue=*/true);
6697  if (AssignmentOp.isInvalid())
6698  continue;
6699 
6700  // No need to mark vars as copyprivate, they are already threadprivate or
6701  // implicitly private.
6702  Vars.push_back(DE);
6703  SrcExprs.push_back(PseudoSrcExpr);
6704  DstExprs.push_back(PseudoDstExpr);
6705  AssignmentOps.push_back(AssignmentOp.get());
6706  }
6707 
6708  if (Vars.empty())
6709  return nullptr;
6710 
6711  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
6712  Vars, SrcExprs, DstExprs, AssignmentOps);
6713 }
6714 
6716  SourceLocation StartLoc,
6717  SourceLocation LParenLoc,
6718  SourceLocation EndLoc) {
6719  if (VarList.empty())
6720  return nullptr;
6721 
6722  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
6723 }
6724 
6725 OMPClause *
6728  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
6729  SourceLocation LParenLoc, SourceLocation EndLoc) {
6730  if (DepKind == OMPC_DEPEND_unknown) {
6731  std::string Values;
6732  std::string Sep(", ");
6733  for (unsigned i = 0; i < OMPC_DEPEND_unknown; ++i) {
6734  Values += "'";
6735  Values += getOpenMPSimpleClauseTypeName(OMPC_depend, i);
6736  Values += "'";
6737  switch (i) {
6738  case OMPC_DEPEND_unknown - 2:
6739  Values += " or ";
6740  break;
6741  case OMPC_DEPEND_unknown - 1:
6742  break;
6743  default:
6744  Values += Sep;
6745  break;
6746  }
6747  }
6748  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
6749  << Values << getOpenMPClauseName(OMPC_depend);
6750  return nullptr;
6751  }
6753  for (auto &RefExpr : VarList) {
6754  assert(RefExpr && "NULL expr in OpenMP shared clause.");
6755  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6756  // It will be analyzed later.
6757  Vars.push_back(RefExpr);
6758  continue;
6759  }
6760 
6761  SourceLocation ELoc = RefExpr->getExprLoc();
6762  // OpenMP [2.11.1.1, Restrictions, p.3]
6763  // A variable that is part of another variable (such as a field of a
6764  // structure) but is not an array element or an array section cannot appear
6765  // in a depend clause.
6766  auto *SimpleExpr = RefExpr->IgnoreParenCasts();
6767  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
6768  ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
6769  if (!RefExpr->IgnoreParenImpCasts()->isLValue() || (!ASE && !DE) ||
6770  (DE && !isa<VarDecl>(DE->getDecl())) ||
6771  (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
6772  !ASE->getBase()->getType()->isArrayType())) {
6773  Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
6774  << RefExpr->getSourceRange();
6775  continue;
6776  }
6777 
6778  Vars.push_back(RefExpr->IgnoreParenImpCasts());
6779  }
6780 
6781  if (Vars.empty())
6782  return nullptr;
6783 
6784  return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind,
6785  DepLoc, ColonLoc, Vars);
6786 }
6787 
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.
Definition: Stmt.cpp:1193
Expr * NLB
Update of LowerBound for statically sheduled 'omp for' loops.
Definition: StmtOpenMP.h:460
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:13503
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Definition: StmtOpenMP.h:470
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
Definition: StmtOpenMP.h:468
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
Definition: SemaOpenMP.cpp:777
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: Stmt.cpp:1811
void setImplicit(bool I=true)
Definition: DeclBase.h:504
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition: Stmt.h:2104
void setNothrow(bool Nothrow=true)
Definition: Decl.h:3644
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
StringRef getName() const
Definition: Decl.h:168
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
CanQualType VoidPtrTy
Definition: ASTContext.h:831
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:215
bool isInvalid() const
Definition: Ownership.h:159
ArrayRef< OMPClause * > clauses()
Definition: StmtOpenMP.h:203
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition: Expr.h:3051
DeclContext * getCurLexicalContext() const
Definition: Sema.h:8990
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
Definition: SemaStmt.cpp:3779
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)
Definition: SemaExpr.cpp:6478
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
Definition: SemaExpr.cpp:3136
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
Definition: SemaOpenMP.cpp:702
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1733
const LangOptions & getLangOpts() const
Definition: Sema.h:1019
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
DeclClass * getAsSingle() const
Definition: Lookup.h:447
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement...
SourceLocation getEndLoc() const
getEndLoc - Retrieve the location of the last token.
static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start)
Build 'VarRef = Start.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
const Scope * getParent() const
Definition: Scope.h:215
ActionResult< Expr * > ExprResult
Definition: Ownership.h:252
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
Definition: Stmt.cpp:1468
The current expression is potentially evaluated at run time, which means that code may be generated t...
Definition: Sema.h:781
Expr * EUB
EnsureUpperBound – expression LB = min(LB, NumIterations).
Definition: StmtOpenMP.h:458
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition: Sema.h:1088
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
Definition: Decl.cpp:1987
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:154
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
Definition: Stmt.cpp:1422
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: Stmt.cpp:1787
bool isEnumeralType() const
Definition: Type.h:5292
PtrTy get() const
Definition: Ownership.h:163
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: Stmt.cpp:2184
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:851
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
const Expr * getInit() const
Definition: Decl.h:1068
A container of type source information.
Definition: Decl.h:60
This represents 'update' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:866
Wrapper for void* pointer.
Definition: Ownership.h:45
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
SourceLocation getOperatorLoc() const
Definition: Expr.h:2958
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.
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2147
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
SourceLocation getTemplateKeywordLoc() const
Retrieve the location of the template keyword preceding this name, if any.
Definition: Expr.h:1071
static OMPParallelForDirective * 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: Stmt.cpp:1897
This represents 'read' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:808
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:25
bool isFileVarDecl() const
isFileVarDecl - Returns true for file scoped variable declaration.
Definition: Decl.h:1040
DiagnosticsEngine & Diags
Definition: Sema.h:297
This represents 'num_threads' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:261
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
TLSKind getTLSKind() const
Definition: Decl.cpp:1803
varlist_range varlists()
Definition: OpenMPClause.h:119
ExtProtoInfo - Extra information about a function prototype.
Definition: Type.h:3042
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:1701
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:922
Expr * IgnoreImplicit() LLVM_READONLY
Definition: Expr.h:694
void setBegin(SourceLocation b)
Not a TLS variable.
Definition: Decl.h:725
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
static Expr * GetCollapseNumberExpr(ArrayRef< OMPClause * > Clauses)
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition: DeclCXX.h:1163
bool isEmpty() const
No scope specifier.
Definition: DeclSpec.h:194
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
Definition: ScopeInfo.h:582
void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto)
Definition: SemaDecl.cpp:9378
QualType withConst() const
Retrieves a version of this type with const applied. Note that this does not always yield a canonical...
This represents 'safelen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:319
Expr * LastIteration
Loop last iteration number.
Definition: StmtOpenMP.h:436
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
A semantic tree transformation that allows one to transform one abstract syntax tree into another...
Definition: TreeTransform.h:94
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
Definition: OpenMPKinds.cpp:61
DeclarationName getName() const
getName - Returns the embedded declaration name.
bool isScalarType() const
Definition: Type.h:5461
CalcStep
Definition: OpenMPClause.h:304
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: Stmt.cpp:1303
bool isUnset() const
Definition: Ownership.h:161
bool hasAttr() const
Definition: DeclBase.h:487
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL)
Creates clause with a list of variables VL.
Definition: Stmt.cpp:1228
A C++ nested-name-specifier augmented with source location information.
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool isReferenceType() const
Definition: Type.h:5241
SourceLocation getLocStart() const
Returns the starting location of the clause.
Definition: OpenMPClause.h:46
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
Definition: SemaOpenMP.cpp:687
bool isTranslationUnit() const
Definition: DeclBase.h:1243
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:367
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
StmtResult ActOnOpenMPOrderedDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
Defines some OpenMP-specific enums and functions.
bool isOpenMPPrivateVar(VarDecl *VD, unsigned Level)
Definition: SemaOpenMP.cpp:679
void PopExpressionEvaluationContext()
Definition: SemaExpr.cpp:12075
void EndOpenMPClause()
End analysis of clauses.
Definition: SemaOpenMP.cpp:698
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
StorageClass getStorageClass() const
Returns the storage class as written in the source. For the computed linkage of symbol, see getLinkage.
Definition: Decl.h:871
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:95
Expr * getLHS() const
Definition: Expr.h:2964
VerifyDiagnosticConsumer::Directive Directive
ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, Expr *SubExpr)
Definition: SemaExpr.cpp:13708
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
BinaryOperatorKind
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: Lookup.h:30
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:518
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
DeclarationNameInfo getNameInfo() const
Definition: Expr.h:998
bool isFunctionOrMethodVarDecl() const
Definition: Decl.h:966
static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *NestedLoopCountExpr, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
Definition: SemaOpenMP.cpp:465
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:135
StmtResult StmtError()
Definition: Ownership.h:268
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2918
bool isValueDependent() const
Definition: Expr.h:146
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:3334
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
This represents 'default' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:426
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:6024
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps)
Creates clause with a list of variables VL.
Definition: Stmt.cpp:1543
This represents 'final' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:207
This represents 'mergeable' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:779
Expr * CalcLastIteration
Calculation of last iteration.
Definition: StmtOpenMP.h:440
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:68
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
bool isStaticLocal() const
Definition: Decl.h:904
Preprocessor & PP
Definition: Sema.h:294
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:1785
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:726
An ordinary object is located at an address in memory.
Definition: Specifiers.h:111
static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
QualType getType() const
Definition: Decl.h:538
bool isInvalid() const
const LangOptions & LangOpts
Definition: Sema.h:293
Expr * NUB
Update of UpperBound for statically sheduled 'omp for' loops.
Definition: StmtOpenMP.h:462
Expr * Cond
Loop condition.
Definition: StmtOpenMP.h:444
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Expr * PreCond
Loop pre-condition.
Definition: StmtOpenMP.h:442
AnnotatingParser & P
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: Stmt.cpp:1654
Finals[]
Definition: OpenMPClause.h:303
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
Definition: StmtOpenMP.h:432
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:258
bool isNamespace() const
Definition: DeclBase.h:1251
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, bool TypeMayContainAuto)
Definition: SemaDecl.cpp:8838
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:10079
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 OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL)
Definition: DeclOpenMP.cpp:28
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
std::vector< bool > & Stack
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Definition: Expr.h:192
Expr * IterationVarRef
Loop iteration variable.
Definition: StmtOpenMP.h:434
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: Stmt.cpp:2215
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: Stmt.cpp:1569
const Type * getTypePtrOrNull() const
Definition: Type.h:5020
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:496
This represents 'capture' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:896
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
Definition: SemaOpenMP.cpp:694
static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract)
Build 'VarRef = Start + Iter * Step'.
bool isDeclScope(Decl *D)
Definition: Scope.h:306
bool isAnyComplexType() const
Definition: Type.h:5295
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
Definition: DeclBase.cpp:910
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
Inits[]
Gets the list of initial values for linear variables.
Definition: OpenMPClause.h:303
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: Stmt.cpp:1857
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup. Asserts that one was found.
Definition: Lookup.h:457
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'ordered' clause.
Defines the clang::Preprocessor interface.
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, bool AllowFold=true)
Definition: SemaExpr.cpp:11869
OpenMPClauseKind
OpenMP clauses.
Definition: OpenMPKinds.h:33
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
DeclContext * getDeclContext()
Definition: DeclBase.h:381
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
Definition: Expr.cpp:752
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:6354
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
Definition: StmtOpenMP.h:474
This represents 'ordered' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:691
void DiscardCleanupsInEvaluationContext()
Definition: SemaExpr.cpp:12133
bool isDependentType() const
Definition: Type.h:1727
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
This represents 'collapse' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:374
ValueDecl * getDecl()
Definition: Expr.h:994
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2405
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.
Definition: Stmt.cpp:1591
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
Definition: OpenMPKinds.h:50
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name, with source-location information.
Definition: Expr.h:1022
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: Stmt.cpp:2012
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:1893
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
Definition: SemaOpenMP.cpp:40
Expr * NumIterations
Loop number of iterations.
Definition: StmtOpenMP.h:438
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
Definition: Sema.h:4713
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.
Definition: OpenMPClause.h:926
This represents 'untied' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:749
bool isAmbiguous() const
Definition: Lookup.h:241
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:2448
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:3488
Expr * ST
Stride - local variable passed to runtime.
Definition: StmtOpenMP.h:456
void addAttr(Attr *A)
Definition: DeclBase.h:437
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
#define false
Definition: stdbool.h:33
Kind
This captures a statement into a function. For example, the following pragma annotated compound state...
Definition: Stmt.h:1989
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Definition: StmtOpenMP.h:464
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: Stmt.cpp:1877
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
Definition: OpenMPKinds.h:66
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: Stmt.cpp:2123
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: Stmt.cpp:2241
bool isValid() const
Return true if this is a valid SourceLocation object.
OverloadedOperatorKind getCXXOverloadedOperator() const
bool isConstant(ASTContext &Ctx) const
Definition: Type.h:703
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
Definition: DeclSpec.cpp:153
This represents 'schedule' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:566
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:1026
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
Definition: Expr.h:1158
bool isLocalVarDecl() const
Definition: Decl.h:951
void setReferenced(bool R=true)
Definition: DeclBase.h:532
OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:23
IdentifierTable & getIdentifierTable()
Definition: Preprocessor.h:685
QualType withConst() const
Definition: Type.h:736
StmtResult ActOnCapturedRegionEnd(Stmt *S)
Definition: SemaStmt.cpp:3874
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:610
C-style initialization with assignment.
Definition: Decl.h:718
This file defines OpenMP nodes for declarative directives.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:32
OMPClause * ActOnOpenMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
CanQualType VoidTy
Definition: ASTContext.h:817
Describes the kind of initialization being performed, along with location information for tokens rela...
This declaration is only a declaration.
Definition: Decl.h:993
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
bool isTypeDependent() const
Definition: Expr.h:166
SourceLocation getBeginLoc() const
Definition: DeclSpec.h:77
Updates[]
Definition: OpenMPClause.h:303
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.
Definition: Stmt.cpp:1379
bool isFileContext() const
Definition: DeclBase.h:1239
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1137
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
Definition: Sema.cpp:1489
Expr * LB
LowerBound - local variable passed to runtime.
Definition: StmtOpenMP.h:452
void clear(unsigned Size)
Initialize all the fields to null.
Definition: StmtOpenMP.h:482
Expr * Init
Loop iteration variable init.
Definition: StmtOpenMP.h:446
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
#define DSAStack
Definition: SemaOpenMP.cpp:656
SourceLocation getLocStart() const LLVM_READONLY
Definition: Expr.cpp:430
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.cpp:193
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId)
Called on well-formed 'reduction' clause.
static 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: Stmt.cpp:1942
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
QualType getType() const
Definition: Expr.h:125
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
StmtResult ActOnOpenMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
SourceLocation getLocStart() const LLVM_READONLY
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Definition: StmtOpenMP.h:466
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: Stmt.cpp:1988
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:3858
* Step
Definition: OpenMPClause.h:304
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
bool isUsed(bool CheckUsedAttr=true) const
Whether this declaration was used, meaning that a definition is required.
Definition: DeclBase.cpp:305
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition. If this could be a tentative definition (in C)...
Definition: Decl.cpp:1896
bool isLValue() const
Definition: Expr.h:250
This represents clause 'linear' in the '#pragma omp ...' directives.
StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
bool isSingleResult() const
Definition: Lookup.h:248
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate', 'copyin' or 'copyprivate'.
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, unsigned Argument, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ArgumentLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Expr * IgnoreParenImpCasts() LLVM_READONLY
Definition: Expr.cpp:2526
QualType getNonReferenceType() const
Definition: Type.h:5182
bool IsOpenMPCapturedVar(VarDecl *VD)
Check if the specified variable is used in a private clause in Checks if the specified variable is us...
Definition: SemaOpenMP.cpp:658
bool empty() const
Return true if no decls were found.
Definition: Lookup.h:279
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: Stmt.cpp:2164
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
Not an overloaded operator.
Definition: OperatorKinds.h:23
static OMPForDirective * 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: Stmt.cpp:1694
const T * getAs() const
Definition: Type.h:5555
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2066
QualType getCanonicalType() const
Definition: Type.h:5055
This file defines OpenMP AST classes for executable directives and clauses.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, bool IsDecltype=false)
Definition: SemaExpr.cpp:12056
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Definition: Diagnostic.cpp:180
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
Definition: SemaDecl.cpp:1267
Expr * Inc
Loop increment.
Definition: StmtOpenMP.h:448
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Definition: OpenMPKinds.h:58
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: Stmt.cpp:1741
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
Definition: Diagnostic.cpp:102
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1505
QualType withRestrict() const
Definition: Type.h:752
OpenMPDefaultClauseKind
OpenMP attributes for 'default' clause.
Definition: OpenMPKinds.h:42
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1228
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: Stmt.cpp:1831
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
Definition: SemaOpenMP.cpp:902
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:2957
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:982
This represents 'write' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:836
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
Definition: ASTContext.h:879
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
Definition: OpenMPKinds.cpp:31
bool isUsable() const
Definition: Ownership.h:160
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
Definition: SemaOpenMP.cpp:941
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
Definition: DeclBase.cpp:316
bool isTLSSupported() const
Whether the target supports thread-local storage.
X
Definition: SemaDecl.cpp:11429
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Definition: Sema.h:286
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: Stmt.cpp:2038
Expr * UB
UpperBound - local variable passed to runtime.
Definition: StmtOpenMP.h:454
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
Describes the sequence of initializations required to initialize a given object or reference with a s...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:5096
This represents 'nowait' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:720
void setEnd(SourceLocation e)
Represents a C++ struct/union/class.
Definition: DeclCXX.h:285
void setTSCSpec(ThreadStorageClassSpecifier TSC)
Definition: Decl.h:876
Opcode getOpcode() const
Definition: Expr.h:2961
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: Stmt.cpp:2053
Do not present this diagnostic, ignore it.
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:307
bool isArrayType() const
Definition: Type.h:5271
Defines the clang::TargetInfo interface.
Expr * getRHS() const
Definition: Expr.h:2966
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
Definition: DeclBase.h:1290
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: Stmt.cpp:2081
OMPClause * ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
ExprResult ExprError()
Definition: Ownership.h:267
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S)
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: Stmt.cpp:1626
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: Stmt.cpp:2067
static OpaquePtr make(PtrTy P)
Definition: Ownership.h:54
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Definition: DeclSpec.h:201
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
Definition: Expr.h:899
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Definition: Expr.h:404
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable...
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, SourceLocation DepLoc)
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name)
Build a variable declaration for OpenMP loop iteration variable.
Definition: SemaOpenMP.cpp:454
void suppressDiagnostics()
Definition: Lookup.h:522
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:99
static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, const VarDecl *VD, DSAStackTy::DSAVarData DVar, bool IsLoopIterVar=false)
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:450
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
Definition: DeclBase.h:372
ASTContext & Context
Definition: Sema.h:295
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, std::unique_ptr< CorrectionCandidateCallback > CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: Stmt.cpp:2102
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: Stmt.cpp:2142
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:411
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:10511
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:1713
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:260
This represents '#pragma omp threadprivate ...' directive. For example, in the following, both 'a' and 'A::b' are threadprivate:
Definition: DeclOpenMP.h:36
bool isIntegralType(ASTContext &Ctx) const
Determine whether this type is an integral type.
Definition: Type.cpp:1602
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
bool isIntegerType() const
Definition: Type.h:5448
bool hasLocalStorage() const
Definition: Decl.h:887
Helper class that creates diagnostics with optional template instantiation stacks.
Definition: Sema.h:1049
Expr * IgnoreParens() LLVM_READONLY
Definition: Expr.cpp:2408
Iterates over a filtered subrange of clauses applied to a directive.
Definition: StmtOpenMP.h:97
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
bool isPointerType() const
Definition: Type.h:5232
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
Definition: Stmt.cpp:1279