Clang Project

clang_source_code/lib/Sema/SemaOpenMP.cpp
1//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements semantic analysis for OpenMP directives and
10/// clauses.
11///
12//===----------------------------------------------------------------------===//
13
14#include "TreeTransform.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/CXXInheritance.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"
24#include "clang/AST/TypeOrdering.h"
25#include "clang/Basic/OpenMPKinds.h"
26#include "clang/Sema/Initialization.h"
27#include "clang/Sema/Lookup.h"
28#include "clang/Sema/Scope.h"
29#include "clang/Sema/ScopeInfo.h"
30#include "clang/Sema/SemaInternal.h"
31#include "llvm/ADT/PointerEmbeddedInt.h"
32using namespace clang;
33
34//===----------------------------------------------------------------------===//
35// Stack of data-sharing attributes for variables
36//===----------------------------------------------------------------------===//
37
38static const Expr *checkMapClauseExpressionBase(
39    Sema &SemaRefExpr *E,
40    OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
41    OpenMPClauseKind CKindbool NoDiagnose);
42
43namespace {
44/// Default data sharing attributes, which can be applied to directive.
45enum DefaultDataSharingAttributes {
46  DSA_unspecified = 0/// Data sharing attribute not specified.
47  DSA_none = 1 << 0,   /// Default data sharing attribute 'none'.
48  DSA_shared = 1 << 1/// Default data sharing attribute 'shared'.
49};
50
51/// Attributes of the defaultmap clause.
52enum DefaultMapAttributes {
53  DMA_unspecified,   /// Default mapping is not specified.
54  DMA_tofrom_scalar/// Default mapping is 'tofrom:scalar'.
55};
56
57/// Stack for tracking declarations used in OpenMP directives and
58/// clauses and their data-sharing attributes.
59class DSAStackTy {
60public:
61  struct DSAVarData {
62    OpenMPDirectiveKind DKind = OMPD_unknown;
63    OpenMPClauseKind CKind = OMPC_unknown;
64    const Expr *RefExpr = nullptr;
65    DeclRefExpr *PrivateCopy = nullptr;
66    SourceLocation ImplicitDSALoc;
67    DSAVarData() = default;
68    DSAVarData(OpenMPDirectiveKind DKindOpenMPClauseKind CKind,
69               const Expr *RefExprDeclRefExpr *PrivateCopy,
70               SourceLocation ImplicitDSALoc)
71        : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
72          PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
73  };
74  using OperatorOffsetTy =
75      llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
76  using DoacrossDependMapTy =
77      llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
78
79private:
80  struct DSAInfo {
81    OpenMPClauseKind Attributes = OMPC_unknown;
82    /// Pointer to a reference expression and a flag which shows that the
83    /// variable is marked as lastprivate(true) or not (false).
84    llvm::PointerIntPair<const Expr *, 1boolRefExpr;
85    DeclRefExpr *PrivateCopy = nullptr;
86  };
87  using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
88  using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
89  using LCDeclInfo = std::pair<unsignedVarDecl *>;
90  using LoopControlVariablesMapTy =
91      llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
92  /// Struct that associates a component with the clause kind where they are
93  /// found.
94  struct MappedExprComponentTy {
95    OMPClauseMappableExprCommon::MappableExprComponentLists Components;
96    OpenMPClauseKind Kind = OMPC_unknown;
97  };
98  using MappedExprComponentsTy =
99      llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
100  using CriticalsWithHintsTy =
101      llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
102  struct ReductionData {
103    using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
104    SourceRange ReductionRange;
105    llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
106    ReductionData() = default;
107    void set(BinaryOperatorKind BOSourceRange RR) {
108      ReductionRange = RR;
109      ReductionOp = BO;
110    }
111    void set(const Expr *RefExprSourceRange RR) {
112      ReductionRange = RR;
113      ReductionOp = RefExpr;
114    }
115  };
116  using DeclReductionMapTy =
117      llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
118
119  struct SharingMapTy {
120    DeclSAMapTy SharingMap;
121    DeclReductionMapTy ReductionMap;
122    AlignedMapTy AlignedMap;
123    MappedExprComponentsTy MappedExprComponents;
124    LoopControlVariablesMapTy LCVMap;
125    DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
126    SourceLocation DefaultAttrLoc;
127    DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
128    SourceLocation DefaultMapAttrLoc;
129    OpenMPDirectiveKind Directive = OMPD_unknown;
130    DeclarationNameInfo DirectiveName;
131    Scope *CurScope = nullptr;
132    SourceLocation ConstructLoc;
133    /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
134    /// get the data (loop counters etc.) about enclosing loop-based construct.
135    /// This data is required during codegen.
136    DoacrossDependMapTy DoacrossDepends;
137    /// First argument (Expr *) contains optional argument of the
138    /// 'ordered' clause, the second one is true if the regions has 'ordered'
139    /// clause, false otherwise.
140    llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
141    unsigned AssociatedLoops = 1;
142    const Decl *PossiblyLoopCounter = nullptr;
143    bool NowaitRegion = false;
144    bool CancelRegion = false;
145    bool LoopStart = false;
146    SourceLocation InnerTeamsRegionLoc;
147    /// Reference to the taskgroup task_reduction reference expression.
148    Expr *TaskgroupReductionRef = nullptr;
149    llvm::DenseSet<QualType> MappedClassesQualTypes;
150    /// List of globals marked as declare target link in this target region
151    /// (isOpenMPTargetExecutionDirective(Directive) == true).
152    llvm::SmallVector<DeclRefExpr *, 4DeclareTargetLinkVarDecls;
153    SharingMapTy(OpenMPDirectiveKind DKindDeclarationNameInfo Name,
154                 Scope *CurScopeSourceLocation Loc)
155        : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
156          ConstructLoc(Loc) {}
157    SharingMapTy() = default;
158  };
159
160  using StackTy = SmallVector<SharingMapTy4>;
161
162  /// Stack of used declaration and their data-sharing attributes.
163  DeclSAMapTy Threadprivates;
164  const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
165  SmallVector<std::pair<StackTyconst FunctionScopeInfo *>, 4Stack;
166  /// true, if check for DSA must be from parent directive, false, if
167  /// from current directive.
168  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
169  Sema &SemaRef;
170  bool ForceCapturing = false;
171  /// true if all the vaiables in the target executable directives must be
172  /// captured by reference.
173  bool ForceCaptureByReferenceInTargetExecutable = false;
174  CriticalsWithHintsTy Criticals;
175
176  using iterator = StackTy::const_reverse_iterator;
177
178  DSAVarData getDSA(iterator &IterValueDecl *Dconst;
179
180  /// Checks if the variable is a local for OpenMP region.
181  bool isOpenMPLocal(VarDecl *D, iterator Iterconst;
182
183  bool isStackEmpty() const {
184    return Stack.empty() ||
185           Stack.back().second != CurrentNonCapturingFunctionScope ||
186           Stack.back().first.empty();
187  }
188
189  /// Vector of previously declared requires directives
190  SmallVector<const OMPRequiresDecl *, 2RequiresDecls;
191  /// omp_allocator_handle_t type.
192  QualType OMPAllocatorHandleT;
193  /// Expression for the predefined allocators.
194  Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
195      nullptr};
196
197public:
198  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
199
200  /// Sets omp_allocator_handle_t type.
201  void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
202  /// Gets omp_allocator_handle_t type.
203  QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
204  /// Sets the given default allocator.
205  void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
206                    Expr *Allocator) {
207    OMPPredefinedAllocators[AllocatorKind] = Allocator;
208  }
209  /// Returns the specified default allocator.
210  Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKindconst {
211    return OMPPredefinedAllocators[AllocatorKind];
212  }
213
214  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
215  OpenMPClauseKind getClauseParsingMode() const {
216     (0) . __assert_fail ("isClauseParsingMode() && \"Must be in clause parsing mode.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 216, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isClauseParsingMode() && "Must be in clause parsing mode.");
217    return ClauseKindMode;
218  }
219  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
220
221  bool isForceVarCapturing() const { return ForceCapturing; }
222  void setForceVarCapturing(bool V) { ForceCapturing = V; }
223
224  void setForceCaptureByReferenceInTargetExecutable(bool V) {
225    ForceCaptureByReferenceInTargetExecutable = V;
226  }
227  bool isForceCaptureByReferenceInTargetExecutable() const {
228    return ForceCaptureByReferenceInTargetExecutable;
229  }
230
231  void push(OpenMPDirectiveKind DKindconst DeclarationNameInfo &DirName,
232            Scope *CurScopeSourceLocation Loc) {
233    if (Stack.empty() ||
234        Stack.back().second != CurrentNonCapturingFunctionScope)
235      Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
236    Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
237    Stack.back().first.back().DefaultAttrLoc = Loc;
238  }
239
240  void pop() {
241     (0) . __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 242, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!Stack.back().first.empty() &&
242 (0) . __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 242, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Data-sharing attributes stack is empty!");
243    Stack.back().first.pop_back();
244  }
245
246  /// Marks that we're started loop parsing.
247  void loopInit() {
248     (0) . __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 249, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isOpenMPLoopDirective(getCurrentDirective()) &&
249 (0) . __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 249, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Expected loop-based directive.");
250    Stack.back().first.back().LoopStart = true;
251  }
252  /// Start capturing of the variables in the loop context.
253  void loopStart() {
254     (0) . __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 255, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isOpenMPLoopDirective(getCurrentDirective()) &&
255 (0) . __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 255, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Expected loop-based directive.");
256    Stack.back().first.back().LoopStart = false;
257  }
258  /// true, if variables are captured, false otherwise.
259  bool isLoopStarted() const {
260     (0) . __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 261, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isOpenMPLoopDirective(getCurrentDirective()) &&
261 (0) . __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 261, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Expected loop-based directive.");
262    return !Stack.back().first.back().LoopStart;
263  }
264  /// Marks (or clears) declaration as possibly loop counter.
265  void resetPossibleLoopCounter(const Decl *D = nullptr) {
266    Stack.back().first.back().PossiblyLoopCounter =
267        D ? D->getCanonicalDecl() : D;
268  }
269  /// Gets the possible loop counter decl.
270  const Decl *getPossiblyLoopCunter() const {
271    return Stack.back().first.back().PossiblyLoopCounter;
272  }
273  /// Start new OpenMP region stack in new non-capturing function.
274  void pushFunction() {
275    const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
276    (CurFnScope)", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 276, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isa<CapturingScopeInfo>(CurFnScope));
277    CurrentNonCapturingFunctionScope = CurFnScope;
278  }
279  /// Pop region stack for non-capturing function.
280  void popFunction(const FunctionScopeInfo *OldFSI) {
281    if (!Stack.empty() && Stack.back().second == OldFSI) {
282      assert(Stack.back().first.empty());
283      Stack.pop_back();
284    }
285    CurrentNonCapturingFunctionScope = nullptr;
286    for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
287      if (!isa<CapturingScopeInfo>(FSI)) {
288        CurrentNonCapturingFunctionScope = FSI;
289        break;
290      }
291    }
292  }
293
294  void addCriticalWithHint(const OMPCriticalDirective *Dllvm::APSInt Hint) {
295    Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
296  }
297  const std::pair<const OMPCriticalDirective *, llvm::APSInt>
298  getCriticalWithHint(const DeclarationNameInfo &Nameconst {
299    auto I = Criticals.find(Name.getAsString());
300    if (I != Criticals.end())
301      return I->second;
302    return std::make_pair(nullptr, llvm::APSInt());
303  }
304  /// If 'aligned' declaration for given variable \a D was not seen yet,
305  /// add it and return NULL; otherwise return previous occurrence's expression
306  /// for diagnostics.
307  const Expr *addUniqueAligned(const ValueDecl *Dconst Expr *NewDE);
308
309  /// Register specified variable as loop control variable.
310  void addLoopControlVariable(const ValueDecl *DVarDecl *Capture);
311  /// Check if the specified variable is a loop control variable for
312  /// current region.
313  /// \return The index of the loop control variable in the list of associated
314  /// for-loops (from outer to inner).
315  const LCDeclInfo isLoopControlVariable(const ValueDecl *Dconst;
316  /// Check if the specified variable is a loop control variable for
317  /// parent region.
318  /// \return The index of the loop control variable in the list of associated
319  /// for-loops (from outer to inner).
320  const LCDeclInfo isParentLoopControlVariable(const ValueDecl *Dconst;
321  /// Get the loop control variable for the I-th loop (or nullptr) in
322  /// parent directive.
323  const ValueDecl *getParentLoopControlVariable(unsigned Iconst;
324
325  /// Adds explicit data sharing attribute to the specified declaration.
326  void addDSA(const ValueDecl *Dconst Expr *EOpenMPClauseKind A,
327              DeclRefExpr *PrivateCopy = nullptr);
328
329  /// Adds additional information for the reduction items with the reduction id
330  /// represented as an operator.
331  void addTaskgroupReductionData(const ValueDecl *DSourceRange SR,
332                                 BinaryOperatorKind BOK);
333  /// Adds additional information for the reduction items with the reduction id
334  /// represented as reduction identifier.
335  void addTaskgroupReductionData(const ValueDecl *DSourceRange SR,
336                                 const Expr *ReductionRef);
337  /// Returns the location and reduction operation from the innermost parent
338  /// region for the given \p D.
339  const DSAVarData
340  getTopMostTaskgroupReductionData(const ValueDecl *DSourceRange &SR,
341                                   BinaryOperatorKind &BOK,
342                                   Expr *&TaskgroupDescriptorconst;
343  /// Returns the location and reduction operation from the innermost parent
344  /// region for the given \p D.
345  const DSAVarData
346  getTopMostTaskgroupReductionData(const ValueDecl *DSourceRange &SR,
347                                   const Expr *&ReductionRef,
348                                   Expr *&TaskgroupDescriptorconst;
349  /// Return reduction reference expression for the current taskgroup.
350  Expr *getTaskgroupReductionRef() const {
351     (0) . __assert_fail ("Stack.back().first.back().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 353, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
352 (0) . __assert_fail ("Stack.back().first.back().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 353, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "taskgroup reference expression requested for non taskgroup "
353 (0) . __assert_fail ("Stack.back().first.back().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 353, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "directive.");
354    return Stack.back().first.back().TaskgroupReductionRef;
355  }
356  /// Checks if the given \p VD declaration is actually a taskgroup reduction
357  /// descriptor variable at the \p Level of OpenMP regions.
358  bool isTaskgroupReductionRef(const ValueDecl *VDunsigned Levelconst {
359    return Stack.back().first[Level].TaskgroupReductionRef &&
360           cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
361                   ->getDecl() == VD;
362  }
363
364  /// Returns data sharing attributes from top of the stack for the
365  /// specified declaration.
366  const DSAVarData getTopDSA(ValueDecl *Dbool FromParent);
367  /// Returns data-sharing attributes for the specified declaration.
368  const DSAVarData getImplicitDSA(ValueDecl *Dbool FromParentconst;
369  /// Checks if the specified variables has data-sharing attributes which
370  /// match specified \a CPred predicate in any directive which matches \a DPred
371  /// predicate.
372  const DSAVarData
373  hasDSA(ValueDecl *Dconst llvm::function_ref<bool(OpenMPClauseKind)> CPred,
374         const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
375         bool FromParentconst;
376  /// Checks if the specified variables has data-sharing attributes which
377  /// match specified \a CPred predicate in any innermost directive which
378  /// matches \a DPred predicate.
379  const DSAVarData
380  hasInnermostDSA(ValueDecl *D,
381                  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
382                  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
383                  bool FromParentconst;
384  /// Checks if the specified variables has explicit data-sharing
385  /// attributes which match specified \a CPred predicate at the specified
386  /// OpenMP region.
387  bool hasExplicitDSA(const ValueDecl *D,
388                      const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
389                      unsigned Levelbool NotLastprivate = falseconst;
390
391  /// Returns true if the directive at level \Level matches in the
392  /// specified \a DPred predicate.
393  bool hasExplicitDirective(
394      const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
395      unsigned Levelconst;
396
397  /// Finds a directive which matches specified \a DPred predicate.
398  bool hasDirective(
399      const llvm::function_ref<bool(
400          OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
401          DPred,
402      bool FromParentconst;
403
404  /// Returns currently analyzed directive.
405  OpenMPDirectiveKind getCurrentDirective() const {
406    return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
407  }
408  /// Returns directive kind at specified level.
409  OpenMPDirectiveKind getDirective(unsigned Levelconst {
410     (0) . __assert_fail ("!isStackEmpty() && \"No directive at specified level.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 410, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && "No directive at specified level.");
411    return Stack.back().first[Level].Directive;
412  }
413  /// Returns parent directive.
414  OpenMPDirectiveKind getParentDirective() const {
415    if (isStackEmpty() || Stack.back().first.size() == 1)
416      return OMPD_unknown;
417    return std::next(Stack.back().first.rbegin())->Directive;
418  }
419
420  /// Add requires decl to internal vector
421  void addRequiresDecl(OMPRequiresDecl *RD) {
422    RequiresDecls.push_back(RD);
423  }
424
425  /// Checks if the defined 'requires' directive has specified type of clause.
426  template <typename ClauseType>
427  bool hasRequiresDeclWithClause() {
428    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
429      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
430        return isa<ClauseType>(C);
431      });
432    });
433  }
434
435  /// Checks for a duplicate clause amongst previously declared requires
436  /// directives
437  bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseListconst {
438    bool IsDuplicate = false;
439    for (OMPClause *CNew : ClauseList) {
440      for (const OMPRequiresDecl *D : RequiresDecls) {
441        for (const OMPClause *CPrev : D->clauselists()) {
442          if (CNew->getClauseKind() == CPrev->getClauseKind()) {
443            SemaRef.Diag(CNew->getBeginLoc(),
444                         diag::err_omp_requires_clause_redeclaration)
445                << getOpenMPClauseName(CNew->getClauseKind());
446            SemaRef.Diag(CPrev->getBeginLoc(),
447                         diag::note_omp_requires_previous_clause)
448                << getOpenMPClauseName(CPrev->getClauseKind());
449            IsDuplicate = true;
450          }
451        }
452      }
453    }
454    return IsDuplicate;
455  }
456
457  /// Set default data sharing attribute to none.
458  void setDefaultDSANone(SourceLocation Loc) {
459    assert(!isStackEmpty());
460    Stack.back().first.back().DefaultAttr = DSA_none;
461    Stack.back().first.back().DefaultAttrLoc = Loc;
462  }
463  /// Set default data sharing attribute to shared.
464  void setDefaultDSAShared(SourceLocation Loc) {
465    assert(!isStackEmpty());
466    Stack.back().first.back().DefaultAttr = DSA_shared;
467    Stack.back().first.back().DefaultAttrLoc = Loc;
468  }
469  /// Set default data mapping attribute to 'tofrom:scalar'.
470  void setDefaultDMAToFromScalar(SourceLocation Loc) {
471    assert(!isStackEmpty());
472    Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
473    Stack.back().first.back().DefaultMapAttrLoc = Loc;
474  }
475
476  DefaultDataSharingAttributes getDefaultDSA() const {
477    return isStackEmpty() ? DSA_unspecified
478                          : Stack.back().first.back().DefaultAttr;
479  }
480  SourceLocation getDefaultDSALocation() const {
481    return isStackEmpty() ? SourceLocation()
482                          : Stack.back().first.back().DefaultAttrLoc;
483  }
484  DefaultMapAttributes getDefaultDMA() const {
485    return isStackEmpty() ? DMA_unspecified
486                          : Stack.back().first.back().DefaultMapAttr;
487  }
488  DefaultMapAttributes getDefaultDMAAtLevel(unsigned Levelconst {
489    return Stack.back().first[Level].DefaultMapAttr;
490  }
491  SourceLocation getDefaultDMALocation() const {
492    return isStackEmpty() ? SourceLocation()
493                          : Stack.back().first.back().DefaultMapAttrLoc;
494  }
495
496  /// Checks if the specified variable is a threadprivate.
497  bool isThreadPrivate(VarDecl *D) {
498    const DSAVarData DVar = getTopDSA(Dfalse);
499    return isOpenMPThreadPrivate(DVar.CKind);
500  }
501
502  /// Marks current region as ordered (it has an 'ordered' clause).
503  void setOrderedRegion(bool IsOrderedconst Expr *Param,
504                        OMPOrderedClause *Clause) {
505    assert(!isStackEmpty());
506    if (IsOrdered)
507      Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
508    else
509      Stack.back().first.back().OrderedRegion.reset();
510  }
511  /// Returns true, if region is ordered (has associated 'ordered' clause),
512  /// false - otherwise.
513  bool isOrderedRegion() const {
514    if (isStackEmpty())
515      return false;
516    return Stack.back().first.rbegin()->OrderedRegion.hasValue();
517  }
518  /// Returns optional parameter for the ordered region.
519  std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
520    if (isStackEmpty() ||
521        !Stack.back().first.rbegin()->OrderedRegion.hasValue())
522      return std::make_pair(nullptrnullptr);
523    return Stack.back().first.rbegin()->OrderedRegion.getValue();
524  }
525  /// Returns true, if parent region is ordered (has associated
526  /// 'ordered' clause), false - otherwise.
527  bool isParentOrderedRegion() const {
528    if (isStackEmpty() || Stack.back().first.size() == 1)
529      return false;
530    return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
531  }
532  /// Returns optional parameter for the ordered region.
533  std::pair<const Expr *, OMPOrderedClause *>
534  getParentOrderedRegionParam() const {
535    if (isStackEmpty() || Stack.back().first.size() == 1 ||
536        !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
537      return std::make_pair(nullptrnullptr);
538    return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
539  }
540  /// Marks current region as nowait (it has a 'nowait' clause).
541  void setNowaitRegion(bool IsNowait = true) {
542    assert(!isStackEmpty());
543    Stack.back().first.back().NowaitRegion = IsNowait;
544  }
545  /// Returns true, if parent region is nowait (has associated
546  /// 'nowait' clause), false - otherwise.
547  bool isParentNowaitRegion() const {
548    if (isStackEmpty() || Stack.back().first.size() == 1)
549      return false;
550    return std::next(Stack.back().first.rbegin())->NowaitRegion;
551  }
552  /// Marks parent region as cancel region.
553  void setParentCancelRegion(bool Cancel = true) {
554    if (!isStackEmpty() && Stack.back().first.size() > 1) {
555      auto &StackElemRef = *std::next(Stack.back().first.rbegin());
556      StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
557    }
558  }
559  /// Return true if current region has inner cancel construct.
560  bool isCancelRegion() const {
561    return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
562  }
563
564  /// Set collapse value for the region.
565  void setAssociatedLoops(unsigned Val) {
566    assert(!isStackEmpty());
567    Stack.back().first.back().AssociatedLoops = Val;
568  }
569  /// Return collapse value for region.
570  unsigned getAssociatedLoops() const {
571    return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
572  }
573
574  /// Marks current target region as one with closely nested teams
575  /// region.
576  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
577    if (!isStackEmpty() && Stack.back().first.size() > 1) {
578      std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
579          TeamsRegionLoc;
580    }
581  }
582  /// Returns true, if current region has closely nested teams region.
583  bool hasInnerTeamsRegion() const {
584    return getInnerTeamsRegionLoc().isValid();
585  }
586  /// Returns location of the nested teams region (if any).
587  SourceLocation getInnerTeamsRegionLoc() const {
588    return isStackEmpty() ? SourceLocation()
589                          : Stack.back().first.back().InnerTeamsRegionLoc;
590  }
591
592  Scope *getCurScope() const {
593    return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
594  }
595  SourceLocation getConstructLoc() const {
596    return isStackEmpty() ? SourceLocation()
597                          : Stack.back().first.back().ConstructLoc;
598  }
599
600  /// Do the check specified in \a Check to all component lists and return true
601  /// if any issue is found.
602  bool checkMappableExprComponentListsForDecl(
603      const ValueDecl *VDbool CurrentRegionOnly,
604      const llvm::function_ref<
605          bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
606               OpenMPClauseKind)>
607          Checkconst {
608    if (isStackEmpty())
609      return false;
610    auto SI = Stack.back().first.rbegin();
611    auto SE = Stack.back().first.rend();
612
613    if (SI == SE)
614      return false;
615
616    if (CurrentRegionOnly)
617      SE = std::next(SI);
618    else
619      std::advance(SI, 1);
620
621    for (; SI != SE; ++SI) {
622      auto MI = SI->MappedExprComponents.find(VD);
623      if (MI != SI->MappedExprComponents.end())
624        for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
625             MI->second.Components)
626          if (Check(L, MI->second.Kind))
627            return true;
628    }
629    return false;
630  }
631
632  /// Do the check specified in \a Check to all component lists at a given level
633  /// and return true if any issue is found.
634  bool checkMappableExprComponentListsForDeclAtLevel(
635      const ValueDecl *VDunsigned Level,
636      const llvm::function_ref<
637          bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
638               OpenMPClauseKind)>
639          Checkconst {
640    if (isStackEmpty())
641      return false;
642
643    auto StartI = Stack.back().first.begin();
644    auto EndI = Stack.back().first.end();
645    if (std::distance(StartI, EndI) <= (int)Level)
646      return false;
647    std::advance(StartI, Level);
648
649    auto MI = StartI->MappedExprComponents.find(VD);
650    if (MI != StartI->MappedExprComponents.end())
651      for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
652           MI->second.Components)
653        if (Check(L, MI->second.Kind))
654          return true;
655    return false;
656  }
657
658  /// Create a new mappable expression component list associated with a given
659  /// declaration and initialize it with the provided list of components.
660  void addMappableExpressionComponents(
661      const ValueDecl *VD,
662      OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
663      OpenMPClauseKind WhereFoundClauseKind) {
664     (0) . __assert_fail ("!isStackEmpty() && \"Not expecting to retrieve components from a empty stack!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 665, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() &&
665 (0) . __assert_fail ("!isStackEmpty() && \"Not expecting to retrieve components from a empty stack!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 665, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Not expecting to retrieve components from a empty stack!");
666    MappedExprComponentTy &MEC =
667        Stack.back().first.back().MappedExprComponents[VD];
668    // Create new entry and append the new components there.
669    MEC.Components.resize(MEC.Components.size() + 1);
670    MEC.Components.back().append(Components.begin(), Components.end());
671    MEC.Kind = WhereFoundClauseKind;
672  }
673
674  unsigned getNestingLevel() const {
675    assert(!isStackEmpty());
676    return Stack.back().first.size() - 1;
677  }
678  void addDoacrossDependClause(OMPDependClause *C,
679                               const OperatorOffsetTy &OpsOffs) {
680     1", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 680, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && Stack.back().first.size() > 1);
681    SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
682    assert(isOpenMPWorksharingDirective(StackElem.Directive));
683    StackElem.DoacrossDepends.try_emplace(COpsOffs);
684  }
685  llvm::iterator_range<DoacrossDependMapTy::const_iterator>
686  getDoacrossDependClauses() const {
687    assert(!isStackEmpty());
688    const SharingMapTy &StackElem = Stack.back().first.back();
689    if (isOpenMPWorksharingDirective(StackElem.Directive)) {
690      const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
691      return llvm::make_range(Ref.begin(), Ref.end());
692    }
693    return llvm::make_range(StackElem.DoacrossDepends.end(),
694                            StackElem.DoacrossDepends.end());
695  }
696
697  // Store types of classes which have been explicitly mapped
698  void addMappedClassesQualTypes(QualType QT) {
699    SharingMapTy &StackElem = Stack.back().first.back();
700    StackElem.MappedClassesQualTypes.insert(QT);
701  }
702
703  // Return set of mapped classes types
704  bool isClassPreviouslyMapped(QualType QTconst {
705    const SharingMapTy &StackElem = Stack.back().first.back();
706    return StackElem.MappedClassesQualTypes.count(QT) != 0;
707  }
708
709  /// Adds global declare target to the parent target region.
710  void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
711     (0) . __assert_fail ("*OMPDeclareTargetDeclAttr..isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr..MT_Link && \"Expected declare target link global.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 713, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
712 (0) . __assert_fail ("*OMPDeclareTargetDeclAttr..isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr..MT_Link && \"Expected declare target link global.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 713, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">               E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
713 (0) . __assert_fail ("*OMPDeclareTargetDeclAttr..isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr..MT_Link && \"Expected declare target link global.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 713, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Expected declare target link global.");
714    if (isStackEmpty())
715      return;
716    auto It = Stack.back().first.rbegin();
717    while (It != Stack.back().first.rend() &&
718           !isOpenMPTargetExecutionDirective(It->Directive))
719      ++It;
720    if (It != Stack.back().first.rend()) {
721       (0) . __assert_fail ("isOpenMPTargetExecutionDirective(It->Directive) && \"Expected target executable directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 722, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isOpenMPTargetExecutionDirective(It->Directive) &&
722 (0) . __assert_fail ("isOpenMPTargetExecutionDirective(It->Directive) && \"Expected target executable directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 722, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">             "Expected target executable directive.");
723      It->DeclareTargetLinkVarDecls.push_back(E);
724    }
725  }
726
727  /// Returns the list of globals with declare target link if current directive
728  /// is target.
729  ArrayRef<DeclRefExpr *> getLinkGlobals() const {
730     (0) . __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 731, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
731 (0) . __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 731, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Expected target executable directive.");
732    return Stack.back().first.back().DeclareTargetLinkVarDecls;
733  }
734};
735
736bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
737  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
738}
739
740bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
741  return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown;
742}
743
744// namespace
745
746static const Expr *getExprAsWritten(const Expr *E) {
747  if (const auto *FE = dyn_cast<FullExpr>(E))
748    E = FE->getSubExpr();
749
750  if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
751    E = MTE->GetTemporaryExpr();
752
753  while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
754    E = Binder->getSubExpr();
755
756  if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
757    E = ICE->getSubExprAsWritten();
758  return E->IgnoreParens();
759}
760
761static Expr *getExprAsWritten(Expr *E) {
762  return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
763}
764
765static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
766  if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
767    if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
768      D = ME->getMemberDecl();
769  const auto *VD = dyn_cast<VarDecl>(D);
770  const auto *FD = dyn_cast<FieldDecl>(D);
771  if (VD != nullptr) {
772    VD = VD->getCanonicalDecl();
773    D = VD;
774  } else {
775    assert(FD);
776    FD = FD->getCanonicalDecl();
777    D = FD;
778  }
779  return D;
780}
781
782static ValueDecl *getCanonicalDecl(ValueDecl *D) {
783  return const_cast<ValueDecl *>(
784      getCanonicalDecl(const_cast<const ValueDecl *>(D)));
785}
786
787DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
788                                          ValueDecl *Dconst {
789  D = getCanonicalDecl(D);
790  auto *VD = dyn_cast<VarDecl>(D);
791  const auto *FD = dyn_cast<FieldDecl>(D);
792  DSAVarData DVar;
793  if (isStackEmpty() || Iter == Stack.back().first.rend()) {
794    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
795    // in a region but not in construct]
796    //  File-scope or namespace-scope variables referenced in called routines
797    //  in the region are shared unless they appear in a threadprivate
798    //  directive.
799    if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
800      DVar.CKind = OMPC_shared;
801
802    // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
803    // in a region but not in construct]
804    //  Variables with static storage duration that are declared in called
805    //  routines in the region are shared.
806    if (VD && VD->hasGlobalStorage())
807      DVar.CKind = OMPC_shared;
808
809    // Non-static data members are shared by default.
810    if (FD)
811      DVar.CKind = OMPC_shared;
812
813    return DVar;
814  }
815
816  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
817  // in a Construct, C/C++, predetermined, p.1]
818  // Variables with automatic storage duration that are declared in a scope
819  // inside the construct are private.
820  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
821      (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
822    DVar.CKind = OMPC_private;
823    return DVar;
824  }
825
826  DVar.DKind = Iter->Directive;
827  // Explicitly specified attributes and local variables with predetermined
828  // attributes.
829  if (Iter->SharingMap.count(D)) {
830    const DSAInfo &Data = Iter->SharingMap.lookup(D);
831    DVar.RefExpr = Data.RefExpr.getPointer();
832    DVar.PrivateCopy = Data.PrivateCopy;
833    DVar.CKind = Data.Attributes;
834    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
835    return DVar;
836  }
837
838  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
839  // in a Construct, C/C++, implicitly determined, p.1]
840  //  In a parallel or task construct, the data-sharing attributes of these
841  //  variables are determined by the default clause, if present.
842  switch (Iter->DefaultAttr) {
843  case DSA_shared:
844    DVar.CKind = OMPC_shared;
845    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
846    return DVar;
847  case DSA_none:
848    return DVar;
849  case DSA_unspecified:
850    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
851    // in a Construct, implicitly determined, p.2]
852    //  In a parallel construct, if no default clause is present, these
853    //  variables are shared.
854    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
855    if (isOpenMPParallelDirective(DVar.DKind) ||
856        isOpenMPTeamsDirective(DVar.DKind)) {
857      DVar.CKind = OMPC_shared;
858      return DVar;
859    }
860
861    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
862    // in a Construct, implicitly determined, p.4]
863    //  In a task construct, if no default clause is present, a variable that in
864    //  the enclosing context is determined to be shared by all implicit tasks
865    //  bound to the current team is shared.
866    if (isOpenMPTaskingDirective(DVar.DKind)) {
867      DSAVarData DVarTemp;
868      iterator I = Iter, E = Stack.back().first.rend();
869      do {
870        ++I;
871        // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
872        // Referenced in a Construct, implicitly determined, p.6]
873        //  In a task construct, if no default clause is present, a variable
874        //  whose data-sharing attribute is not determined by the rules above is
875        //  firstprivate.
876        DVarTemp = getDSA(I, D);
877        if (DVarTemp.CKind != OMPC_shared) {
878          DVar.RefExpr = nullptr;
879          DVar.CKind = OMPC_firstprivate;
880          return DVar;
881        }
882      } while (I != E && !isImplicitTaskingRegion(I->Directive));
883      DVar.CKind =
884          (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
885      return DVar;
886    }
887  }
888  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
889  // in a Construct, implicitly determined, p.3]
890  //  For constructs other than task, if no default clause is present, these
891  //  variables inherit their data-sharing attributes from the enclosing
892  //  context.
893  return getDSA(++Iter, D);
894}
895
896const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
897                                         const Expr *NewDE) {
898   (0) . __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 898, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && "Data sharing attributes stack is empty");
899  D = getCanonicalDecl(D);
900  SharingMapTy &StackElem = Stack.back().first.back();
901  auto It = StackElem.AlignedMap.find(D);
902  if (It == StackElem.AlignedMap.end()) {
903     (0) . __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 903, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
904    StackElem.AlignedMap[D] = NewDE;
905    return nullptr;
906  }
907   (0) . __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 907, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(It->second && "Unexpected nullptr expr in the aligned map");
908  return It->second;
909}
910
911void DSAStackTy::addLoopControlVariable(const ValueDecl *DVarDecl *Capture) {
912   (0) . __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 912, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
913  D = getCanonicalDecl(D);
914  SharingMapTy &StackElem = Stack.back().first.back();
915  StackElem.LCVMap.try_emplace(
916      DLCDeclInfo(StackElem.LCVMap.size() + 1Capture));
917}
918
919const DSAStackTy::LCDeclInfo
920DSAStackTy::isLoopControlVariable(const ValueDecl *Dconst {
921   (0) . __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 921, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
922  D = getCanonicalDecl(D);
923  const SharingMapTy &StackElem = Stack.back().first.back();
924  auto It = StackElem.LCVMap.find(D);
925  if (It != StackElem.LCVMap.end())
926    return It->second;
927  return {0nullptr};
928}
929
930const DSAStackTy::LCDeclInfo
931DSAStackTy::isParentLoopControlVariable(const ValueDecl *Dconst {
932   (0) . __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 933, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
933 (0) . __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 933, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Data-sharing attributes stack is empty");
934  D = getCanonicalDecl(D);
935  const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
936  auto It = StackElem.LCVMap.find(D);
937  if (It != StackElem.LCVMap.end())
938    return It->second;
939  return {0nullptr};
940}
941
942const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned Iconst {
943   (0) . __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 944, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
944 (0) . __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 944, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Data-sharing attributes stack is empty");
945  const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
946  if (StackElem.LCVMap.size() < I)
947    return nullptr;
948  for (const auto &Pair : StackElem.LCVMap)
949    if (Pair.second.first == I)
950      return Pair.first;
951  return nullptr;
952}
953
954void DSAStackTy::addDSA(const ValueDecl *Dconst Expr *EOpenMPClauseKind A,
955                        DeclRefExpr *PrivateCopy) {
956  D = getCanonicalDecl(D);
957  if (A == OMPC_threadprivate) {
958    DSAInfo &Data = Threadprivates[D];
959    Data.Attributes = A;
960    Data.RefExpr.setPointer(E);
961    Data.PrivateCopy = nullptr;
962  } else {
963     (0) . __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 963, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
964    DSAInfo &Data = Stack.back().first.back().SharingMap[D];
965    assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
966           (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
967           (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
968           (isLoopControlVariable(D).first && A == OMPC_private));
969    if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
970      Data.RefExpr.setInt(/*IntVal=*/true);
971      return;
972    }
973    const bool IsLastprivate =
974        A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
975    Data.Attributes = A;
976    Data.RefExpr.setPointerAndInt(EIsLastprivate);
977    Data.PrivateCopy = PrivateCopy;
978    if (PrivateCopy) {
979      DSAInfo &Data =
980          Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
981      Data.Attributes = A;
982      Data.RefExpr.setPointerAndInt(PrivateCopyIsLastprivate);
983      Data.PrivateCopy = nullptr;
984    }
985  }
986}
987
988/// Build a variable declaration for OpenMP loop iteration variable.
989static VarDecl *buildVarDecl(Sema &SemaRefSourceLocation LocQualType Type,
990                             StringRef Nameconst AttrVec *Attrs = nullptr,
991                             DeclRefExpr *OrigRef = nullptr) {
992  DeclContext *DC = SemaRef.CurContext;
993  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
994  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(TypeLoc);
995  auto *Decl =
996      VarDecl::Create(SemaRef.ContextDCLocLocIITypeTInfoSC_None);
997  if (Attrs) {
998    for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
999         I != E; ++I)
1000      Decl->addAttr(*I);
1001  }
1002  Decl->setImplicit();
1003  if (OrigRef) {
1004    Decl->addAttr(
1005        OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1006  }
1007  return Decl;
1008}
1009
1010static DeclRefExpr *buildDeclRefExpr(Sema &SVarDecl *DQualType Ty,
1011                                     SourceLocation Loc,
1012                                     bool RefersToCapture = false) {
1013  D->setReferenced();
1014  D->markUsed(S.Context);
1015  return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1016                             SourceLocation(), DRefersToCaptureLocTy,
1017                             VK_LValue);
1018}
1019
1020void DSAStackTy::addTaskgroupReductionData(const ValueDecl *DSourceRange SR,
1021                                           BinaryOperatorKind BOK) {
1022  D = getCanonicalDecl(D);
1023   (0) . __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1023, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1024   (0) . __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1026, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(
1025 (0) . __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1026, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">      Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
1026 (0) . __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1026, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">      "Additional reduction info may be specified only for reduction items.");
1027  ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
1028   (0) . __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1031, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ReductionData.ReductionRange.isInvalid() &&
1029 (0) . __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1031, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         Stack.back().first.back().Directive == OMPD_taskgroup &&
1030 (0) . __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1031, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Additional reduction info may be specified only once for reduction "
1031 (0) . __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1031, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "items.");
1032  ReductionData.set(BOKSR);
1033  Expr *&TaskgroupReductionRef =
1034      Stack.back().first.back().TaskgroupReductionRef;
1035  if (!TaskgroupReductionRef) {
1036    VarDecl *VD = buildVarDecl(SemaRefSR.getBegin(),
1037                               SemaRef.Context.VoidPtrTy".task_red.");
1038    TaskgroupReductionRef =
1039        buildDeclRefExpr(SemaRefVDSemaRef.Context.VoidPtrTySR.getBegin());
1040  }
1041}
1042
1043void DSAStackTy::addTaskgroupReductionData(const ValueDecl *DSourceRange SR,
1044                                           const Expr *ReductionRef) {
1045  D = getCanonicalDecl(D);
1046   (0) . __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1046, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1047   (0) . __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1049, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(
1048 (0) . __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1049, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">      Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
1049 (0) . __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1049, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">      "Additional reduction info may be specified only for reduction items.");
1050  ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
1051   (0) . __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1054, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ReductionData.ReductionRange.isInvalid() &&
1052 (0) . __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1054, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         Stack.back().first.back().Directive == OMPD_taskgroup &&
1053 (0) . __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1054, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Additional reduction info may be specified only once for reduction "
1054 (0) . __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1054, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "items.");
1055  ReductionData.set(ReductionRefSR);
1056  Expr *&TaskgroupReductionRef =
1057      Stack.back().first.back().TaskgroupReductionRef;
1058  if (!TaskgroupReductionRef) {
1059    VarDecl *VD = buildVarDecl(SemaRefSR.getBegin(),
1060                               SemaRef.Context.VoidPtrTy".task_red.");
1061    TaskgroupReductionRef =
1062        buildDeclRefExpr(SemaRefVDSemaRef.Context.VoidPtrTySR.getBegin());
1063  }
1064}
1065
1066const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1067    const ValueDecl *DSourceRange &SRBinaryOperatorKind &BOK,
1068    Expr *&TaskgroupDescriptorconst {
1069  D = getCanonicalDecl(D);
1070   (0) . __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1070, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1071  if (Stack.back().first.empty())
1072      return DSAVarData();
1073  for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1074                E = Stack.back().first.rend();
1075       I != E; std::advance(I, 1)) {
1076    const DSAInfo &Data = I->SharingMap.lookup(D);
1077    if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1078      continue;
1079    const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1080    if (!ReductionData.ReductionOp ||
1081        ReductionData.ReductionOp.is<const Expr *>())
1082      return DSAVarData();
1083    SR = ReductionData.ReductionRange;
1084    BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1085     (0) . __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1087, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1086 (0) . __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1087, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">                                       "expression for the descriptor is not "
1087 (0) . __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1087, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">                                       "set.");
1088    TaskgroupDescriptor = I->TaskgroupReductionRef;
1089    return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1090                      Data.PrivateCopy, I->DefaultAttrLoc);
1091  }
1092  return DSAVarData();
1093}
1094
1095const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1096    const ValueDecl *DSourceRange &SRconst Expr *&ReductionRef,
1097    Expr *&TaskgroupDescriptorconst {
1098  D = getCanonicalDecl(D);
1099   (0) . __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1099, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1100  if (Stack.back().first.empty())
1101      return DSAVarData();
1102  for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1103                E = Stack.back().first.rend();
1104       I != E; std::advance(I, 1)) {
1105    const DSAInfo &Data = I->SharingMap.lookup(D);
1106    if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1107      continue;
1108    const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1109    if (!ReductionData.ReductionOp ||
1110        !ReductionData.ReductionOp.is<const Expr *>())
1111      return DSAVarData();
1112    SR = ReductionData.ReductionRange;
1113    ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1114     (0) . __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1116, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1115 (0) . __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1116, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">                                       "expression for the descriptor is not "
1116 (0) . __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1116, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">                                       "set.");
1117    TaskgroupDescriptor = I->TaskgroupReductionRef;
1118    return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1119                      Data.PrivateCopy, I->DefaultAttrLoc);
1120  }
1121  return DSAVarData();
1122}
1123
1124bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iterconst {
1125  D = D->getCanonicalDecl();
1126  if (!isStackEmpty()) {
1127    iterator I = Iter, E = Stack.back().first.rend();
1128    Scope *TopScope = nullptr;
1129    while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) &&
1130           !isOpenMPTargetExecutionDirective(I->Directive))
1131      ++I;
1132    if (I == E)
1133      return false;
1134    TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1135    Scope *CurScope = getCurScope();
1136    while (CurScope != TopScope && !CurScope->isDeclScope(D))
1137      CurScope = CurScope->getParent();
1138    return CurScope != TopScope;
1139  }
1140  return false;
1141}
1142
1143static bool isConstNotMutableType(Sema &SemaRefQualType Type,
1144                                  bool AcceptIfMutable = true,
1145                                  bool *IsClassType = nullptr) {
1146  ASTContext &Context = SemaRef.getASTContext();
1147  Type = Type.getNonReferenceType().getCanonicalType();
1148  bool IsConstant = Type.isConstant(Context);
1149  Type = Context.getBaseElementType(Type);
1150  const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1151                                ? Type->getAsCXXRecordDecl()
1152                                : nullptr;
1153  if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1154    if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1155      RD = CTD->getTemplatedDecl();
1156  if (IsClassType)
1157    *IsClassType = RD;
1158  return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1159                         RD->hasDefinition() && RD->hasMutableFields());
1160}
1161
1162static bool rejectConstNotMutableType(Sema &SemaRefconst ValueDecl *D,
1163                                      QualType TypeOpenMPClauseKind CKind,
1164                                      SourceLocation ELoc,
1165                                      bool AcceptIfMutable = true,
1166                                      bool ListItemNotVar = false) {
1167  ASTContext &Context = SemaRef.getASTContext();
1168  bool IsClassType;
1169  if (isConstNotMutableType(SemaRefTypeAcceptIfMutable, &IsClassType)) {
1170    unsigned Diag = ListItemNotVar
1171                        ? diag::err_omp_const_list_item
1172                        : IsClassType ? diag::err_omp_const_not_mutable_variable
1173                                      : diag::err_omp_const_variable;
1174    SemaRef.Diag(ELocDiag) << getOpenMPClauseName(CKind);
1175    if (!ListItemNotVar && D) {
1176      const VarDecl *VD = dyn_cast<VarDecl>(D);
1177      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1178                               VarDecl::DeclarationOnly;
1179      SemaRef.Diag(D->getLocation(),
1180                   IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1181          << D;
1182    }
1183    return true;
1184  }
1185  return false;
1186}
1187
1188const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1189                                                   bool FromParent) {
1190  D = getCanonicalDecl(D);
1191  DSAVarData DVar;
1192
1193  auto *VD = dyn_cast<VarDecl>(D);
1194  auto TI = Threadprivates.find(D);
1195  if (TI != Threadprivates.end()) {
1196    DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1197    DVar.CKind = OMPC_threadprivate;
1198    return DVar;
1199  }
1200  if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1201    DVar.RefExpr = buildDeclRefExpr(
1202        SemaRef, VD, D->getType().getNonReferenceType(),
1203        VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1204    DVar.CKind = OMPC_threadprivate;
1205    addDSA(DDVar.RefExprOMPC_threadprivate);
1206    return DVar;
1207  }
1208  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1209  // in a Construct, C/C++, predetermined, p.1]
1210  //  Variables appearing in threadprivate directives are threadprivate.
1211  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1212       !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1213         SemaRef.getLangOpts().OpenMPUseTLS &&
1214         SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1215      (VD && VD->getStorageClass() == SC_Register &&
1216       VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1217    DVar.RefExpr = buildDeclRefExpr(
1218        SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1219    DVar.CKind = OMPC_threadprivate;
1220    addDSA(DDVar.RefExprOMPC_threadprivate);
1221    return DVar;
1222  }
1223  if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1224      VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1225      !isLoopControlVariable(D).first) {
1226    iterator IterTarget =
1227        std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
1228                     [](const SharingMapTy &Data) {
1229                       return isOpenMPTargetExecutionDirective(Data.Directive);
1230                     });
1231    if (IterTarget != Stack.back().first.rend()) {
1232      iterator ParentIterTarget = std::next(IterTarget, 1);
1233      for (iterator Iter = Stack.back().first.rbegin();
1234           Iter != ParentIterTarget; std::advance(Iter, 1)) {
1235        if (isOpenMPLocal(VD, Iter)) {
1236          DVar.RefExpr =
1237              buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1238                               D->getLocation());
1239          DVar.CKind = OMPC_threadprivate;
1240          return DVar;
1241        }
1242      }
1243      if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
1244        auto DSAIter = IterTarget->SharingMap.find(D);
1245        if (DSAIter != IterTarget->SharingMap.end() &&
1246            isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1247          DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1248          DVar.CKind = OMPC_threadprivate;
1249          return DVar;
1250        }
1251        iterator End = Stack.back().first.rend();
1252        if (!SemaRef.isOpenMPCapturedByRef(
1253                D, std::distance(ParentIterTarget, End))) {
1254          DVar.RefExpr =
1255              buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1256                               IterTarget->ConstructLoc);
1257          DVar.CKind = OMPC_threadprivate;
1258          return DVar;
1259        }
1260      }
1261    }
1262  }
1263
1264  if (isStackEmpty())
1265    // Not in OpenMP execution region and top scope was already checked.
1266    return DVar;
1267
1268  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1269  // in a Construct, C/C++, predetermined, p.4]
1270  //  Static data members are shared.
1271  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1272  // in a Construct, C/C++, predetermined, p.7]
1273  //  Variables with static storage duration that are declared in a scope
1274  //  inside the construct are shared.
1275  auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1276  if (VD && VD->isStaticDataMember()) {
1277    DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1278    if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1279      return DVar;
1280
1281    DVar.CKind = OMPC_shared;
1282    return DVar;
1283  }
1284
1285  // The predetermined shared attribute for const-qualified types having no
1286  // mutable members was removed after OpenMP 3.1.
1287  if (SemaRef.LangOpts.OpenMP <= 31) {
1288    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1289    // in a Construct, C/C++, predetermined, p.6]
1290    //  Variables with const qualified type having no mutable member are
1291    //  shared.
1292    if (isConstNotMutableType(SemaRefD->getType())) {
1293      // Variables with const-qualified type having no mutable member may be
1294      // listed in a firstprivate clause, even if they are static data members.
1295      DSAVarData DVarTemp = hasInnermostDSA(
1296          D,
1297          [](OpenMPClauseKind C) {
1298            return C == OMPC_firstprivate || C == OMPC_shared;
1299          },
1300          MatchesAlways, FromParent);
1301      if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1302        return DVarTemp;
1303
1304      DVar.CKind = OMPC_shared;
1305      return DVar;
1306    }
1307  }
1308
1309  // Explicitly specified attributes and local variables with predetermined
1310  // attributes.
1311  iterator I = Stack.back().first.rbegin();
1312  iterator EndI = Stack.back().first.rend();
1313  if (FromParent && I != EndI)
1314    std::advance(I, 1);
1315  auto It = I->SharingMap.find(D);
1316  if (It != I->SharingMap.end()) {
1317    const DSAInfo &Data = It->getSecond();
1318    DVar.RefExpr = Data.RefExpr.getPointer();
1319    DVar.PrivateCopy = Data.PrivateCopy;
1320    DVar.CKind = Data.Attributes;
1321    DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1322    DVar.DKind = I->Directive;
1323  }
1324
1325  return DVar;
1326}
1327
1328const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1329                                                        bool FromParentconst {
1330  if (isStackEmpty()) {
1331    iterator I;
1332    return getDSA(I, D);
1333  }
1334  D = getCanonicalDecl(D);
1335  iterator StartI = Stack.back().first.rbegin();
1336  iterator EndI = Stack.back().first.rend();
1337  if (FromParent && StartI != EndI)
1338    std::advance(StartI, 1);
1339  return getDSA(StartI, D);
1340}
1341
1342const DSAStackTy::DSAVarData
1343DSAStackTy::hasDSA(ValueDecl *D,
1344                   const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1345                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1346                   bool FromParentconst {
1347  if (isStackEmpty())
1348    return {};
1349  D = getCanonicalDecl(D);
1350  iterator I = Stack.back().first.rbegin();
1351  iterator EndI = Stack.back().first.rend();
1352  if (FromParent && I != EndI)
1353    std::advance(I, 1);
1354  for (; I != EndI; std::advance(I, 1)) {
1355    if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive))
1356      continue;
1357    iterator NewI = I;
1358    DSAVarData DVar = getDSA(NewI, D);
1359    if (I == NewI && CPred(DVar.CKind))
1360      return DVar;
1361  }
1362  return {};
1363}
1364
1365const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1366    ValueDecl *Dconst llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1367    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1368    bool FromParentconst {
1369  if (isStackEmpty())
1370    return {};
1371  D = getCanonicalDecl(D);
1372  iterator StartI = Stack.back().first.rbegin();
1373  iterator EndI = Stack.back().first.rend();
1374  if (FromParent && StartI != EndI)
1375    std::advance(StartI, 1);
1376  if (StartI == EndI || !DPred(StartI->Directive))
1377    return {};
1378  iterator NewI = StartI;
1379  DSAVarData DVar = getDSA(NewI, D);
1380  return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1381}
1382
1383bool DSAStackTy::hasExplicitDSA(
1384    const ValueDecl *Dconst llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1385    unsigned Levelbool NotLastprivateconst {
1386  if (isStackEmpty())
1387    return false;
1388  D = getCanonicalDecl(D);
1389  auto StartI = Stack.back().first.begin();
1390  auto EndI = Stack.back().first.end();
1391  if (std::distance(StartI, EndI) <= (int)Level)
1392    return false;
1393  std::advance(StartI, Level);
1394  auto I = StartI->SharingMap.find(D);
1395  if ((I != StartI->SharingMap.end()) &&
1396         I->getSecond().RefExpr.getPointer() &&
1397         CPred(I->getSecond().Attributes) &&
1398         (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1399    return true;
1400  // Check predetermined rules for the loop control variables.
1401  auto LI = StartI->LCVMap.find(D);
1402  if (LI != StartI->LCVMap.end())
1403    return CPred(OMPC_private);
1404  return false;
1405}
1406
1407bool DSAStackTy::hasExplicitDirective(
1408    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1409    unsigned Levelconst {
1410  if (isStackEmpty())
1411    return false;
1412  auto StartI = Stack.back().first.begin();
1413  auto EndI = Stack.back().first.end();
1414  if (std::distance(StartI, EndI) <= (int)Level)
1415    return false;
1416  std::advance(StartI, Level);
1417  return DPred(StartI->Directive);
1418}
1419
1420bool DSAStackTy::hasDirective(
1421    const llvm::function_ref<bool(OpenMPDirectiveKind,
1422                                  const DeclarationNameInfo &, SourceLocation)>
1423        DPred,
1424    bool FromParentconst {
1425  // We look only in the enclosing region.
1426  if (isStackEmpty())
1427    return false;
1428  auto StartI = std::next(Stack.back().first.rbegin());
1429  auto EndI = Stack.back().first.rend();
1430  if (FromParent && StartI != EndI)
1431    StartI = std::next(StartI);
1432  for (auto I = StartI, EE = EndI; I != EE; ++I) {
1433    if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1434      return true;
1435  }
1436  return false;
1437}
1438
1439void Sema::InitDataSharingAttributesStack() {
1440  VarDataSharingAttributesStack = new DSAStackTy(*this);
1441}
1442
1443#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1444
1445void Sema::pushOpenMPFunctionRegion() {
1446  DSAStack->pushFunction();
1447}
1448
1449void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1450  DSAStack->popFunction(OldFSI);
1451}
1452
1453static bool isOpenMPDeviceDelayedContext(Sema &S) {
1454   (0) . __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1455, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1455 (0) . __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1455, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Expected OpenMP device compilation.");
1456  return !S.isInOpenMPTargetExecutionDirective() &&
1457         !S.isInOpenMPDeclareTargetContext();
1458}
1459
1460/// Do we know that we will eventually codegen the given function?
1461static bool isKnownEmitted(Sema &SFunctionDecl *FD) {
1462   (0) . __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1463, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1463 (0) . __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1463, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Expected OpenMP device compilation.");
1464  // Templates are emitted when they're instantiated.
1465  if (FD->isDependentContext())
1466    return false;
1467
1468  if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1469          FD->getCanonicalDecl()))
1470    return true;
1471
1472  // Otherwise, the function is known-emitted if it's in our set of
1473  // known-emitted functions.
1474  return S.DeviceKnownEmittedFns.count(FD) > 0;
1475}
1476
1477Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1478                                                     unsigned DiagID) {
1479   (0) . __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1480, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1480 (0) . __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1480, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Expected OpenMP device compilation.");
1481  return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) &&
1482                            !isKnownEmitted(*thisgetCurFunctionDecl()))
1483                               ? DeviceDiagBuilder::K_Deferred
1484                               : DeviceDiagBuilder::K_Immediate,
1485                           LocDiagIDgetCurFunctionDecl(), *this);
1486}
1487
1488void Sema::checkOpenMPDeviceFunction(SourceLocation LocFunctionDecl *Callee) {
1489   (0) . __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1490, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1490 (0) . __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1490, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Expected OpenMP device compilation.");
1491   (0) . __assert_fail ("Callee && \"Callee may not be null.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1491, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Callee && "Callee may not be null.");
1492  FunctionDecl *Caller = getCurFunctionDecl();
1493
1494  // If the caller is known-emitted, mark the callee as known-emitted.
1495  // Otherwise, mark the call in our call graph so we can traverse it later.
1496  if (!isOpenMPDeviceDelayedContext(*this) ||
1497      (Caller && isKnownEmitted(*this, Caller)))
1498    markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted);
1499  else if (Caller)
1500    DeviceCallGraph[Caller].insert({Callee, Loc});
1501}
1502
1503void Sema::checkOpenMPDeviceExpr(const Expr *E) {
1504   (0) . __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"OpenMP device compilation mode is expected.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1505, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
1505 (0) . __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"OpenMP device compilation mode is expected.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1505, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "OpenMP device compilation mode is expected.");
1506  QualType Ty = E->getType();
1507  if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
1508      (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) ||
1509      (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
1510       !Context.getTargetInfo().hasInt128Type()))
1511    targetDiag(E->getExprLoc(), diag::err_type_unsupported)
1512        << Ty << E->getSourceRange();
1513}
1514
1515bool Sema::isOpenMPCapturedByRef(const ValueDecl *Dunsigned Levelconst {
1516   (0) . __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1516, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LangOpts.OpenMP && "OpenMP is not allowed");
1517
1518  ASTContext &Ctx = getASTContext();
1519  bool IsByRef = true;
1520
1521  // Find the directive that is associated with the provided scope.
1522  D = cast<ValueDecl>(D->getCanonicalDecl());
1523  QualType Ty = D->getType();
1524
1525  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirectiveLevel)) {
1526    // This table summarizes how a given variable should be passed to the device
1527    // given its type and the clauses where it appears. This table is based on
1528    // the description in OpenMP 4.5 [2.10.4, target Construct] and
1529    // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1530    //
1531    // =========================================================================
1532    // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
1533    // |      |(tofrom:scalar)|     |  pvt  |               |          |       |
1534    // =========================================================================
1535    // | scl  |               |     |       |       -       |          | bycopy|
1536    // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
1537    // | scl  |               |  x  |   -   |       -       |     -    | null  |
1538    // | scl  |       x       |     |       |       -       |          | byref |
1539    // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
1540    // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
1541    // | scl  |               |  -  |   -   |       -       |     x    | byref |
1542    // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
1543    //
1544    // | agg  |      n.a.     |     |       |       -       |          | byref |
1545    // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
1546    // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
1547    // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
1548    // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
1549    //
1550    // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
1551    // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
1552    // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
1553    // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
1554    // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
1555    // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
1556    // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
1557    // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
1558    // =========================================================================
1559    // Legend:
1560    //  scl - scalar
1561    //  ptr - pointer
1562    //  agg - aggregate
1563    //  x - applies
1564    //  - - invalid in this combination
1565    //  [] - mapped with an array section
1566    //  byref - should be mapped by reference
1567    //  byval - should be mapped by value
1568    //  null - initialize a local variable to null on the device
1569    //
1570    // Observations:
1571    //  - All scalar declarations that show up in a map clause have to be passed
1572    //    by reference, because they may have been mapped in the enclosing data
1573    //    environment.
1574    //  - If the scalar value does not fit the size of uintptr, it has to be
1575    //    passed by reference, regardless the result in the table above.
1576    //  - For pointers mapped by value that have either an implicit map or an
1577    //    array section, the runtime library may pass the NULL value to the
1578    //    device instead of the value passed to it by the compiler.
1579
1580    if (Ty->isReferenceType())
1581      Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1582
1583    // Locate map clauses and see if the variable being captured is referred to
1584    // in any of those clauses. Here we only care about variables, not fields,
1585    // because fields are part of aggregates.
1586    bool IsVariableUsedInMapClause = false;
1587    bool IsVariableAssociatedWithSection = false;
1588
1589    DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1590        DLevel,
1591        [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSectionD](
1592            OMPClauseMappableExprCommon::MappableExprComponentListRef
1593                MapExprComponents,
1594            OpenMPClauseKind WhereFoundClauseKind) {
1595          // Only the map clause information influences how a variable is
1596          // captured. E.g. is_device_ptr does not require changing the default
1597          // behavior.
1598          if (WhereFoundClauseKind != OMPC_map)
1599            return false;
1600
1601          auto EI = MapExprComponents.rbegin();
1602          auto EE = MapExprComponents.rend();
1603
1604           (0) . __assert_fail ("EI != EE && \"Invalid map expression!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1604, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(EI != EE && "Invalid map expression!");
1605
1606          if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1607            IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1608
1609          ++EI;
1610          if (EI == EE)
1611            return false;
1612
1613          if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1614              isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1615              isa<MemberExpr>(EI->getAssociatedExpression())) {
1616            IsVariableAssociatedWithSection = true;
1617            // There is nothing more we need to know about this variable.
1618            return true;
1619          }
1620
1621          // Keep looking for more map info.
1622          return false;
1623        });
1624
1625    if (IsVariableUsedInMapClause) {
1626      // If variable is identified in a map clause it is always captured by
1627      // reference except if it is a pointer that is dereferenced somehow.
1628      IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1629    } else {
1630      // By default, all the data that has a scalar type is mapped by copy
1631      // (except for reduction variables).
1632      IsByRef =
1633          (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1634           !Ty->isAnyPointerType()) ||
1635          !Ty->isScalarType() ||
1636          DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1637          DSAStack->hasExplicitDSA(
1638              D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1639    }
1640  }
1641
1642  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1643    IsByRef =
1644        ((DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1645          !Ty->isAnyPointerType()) ||
1646         !DSAStack->hasExplicitDSA(
1647             D,
1648             [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1649             Level, /*NotLastprivate=*/true)) &&
1650        // If the variable is artificial and must be captured by value - try to
1651        // capture by value.
1652        !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1653          !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1654  }
1655
1656  // When passing data by copy, we need to make sure it fits the uintptr size
1657  // and alignment, because the runtime library only deals with uintptr types.
1658  // If it does not fit the uintptr size, we need to pass the data by reference
1659  // instead.
1660  if (!IsByRef &&
1661      (Ctx.getTypeSizeInChars(Ty) >
1662           Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1663       Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1664    IsByRef = true;
1665  }
1666
1667  return IsByRef;
1668}
1669
1670unsigned Sema::getOpenMPNestingLevel() const {
1671  assert(getLangOpts().OpenMP);
1672  return DSAStack->getNestingLevel();
1673}
1674
1675bool Sema::isInOpenMPTargetExecutionDirective() const {
1676  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1677          !DSAStack->isClauseParsingMode()) ||
1678         DSAStack->hasDirective(
1679             [](OpenMPDirectiveKind Kconst DeclarationNameInfo &,
1680                SourceLocation) -> bool {
1681               return isOpenMPTargetExecutionDirective(K);
1682             },
1683             false);
1684}
1685
1686VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) {
1687   (0) . __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1687, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LangOpts.OpenMP && "OpenMP is not allowed");
1688  D = getCanonicalDecl(D);
1689
1690  // If we are attempting to capture a global variable in a directive with
1691  // 'target' we return true so that this global is also mapped to the device.
1692  //
1693  auto *VD = dyn_cast<VarDecl>(D);
1694  if (VD && !VD->hasLocalStorage()) {
1695    if (isInOpenMPDeclareTargetContext() &&
1696        (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
1697      // Try to mark variable as declare target if it is used in capturing
1698      // regions.
1699      if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1700        checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
1701      return nullptr;
1702    } else if (isInOpenMPTargetExecutionDirective()) {
1703      // If the declaration is enclosed in a 'declare target' directive,
1704      // then it should not be captured.
1705      //
1706      if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1707        return nullptr;
1708      return VD;
1709    }
1710  }
1711  // Capture variables captured by reference in lambdas for target-based
1712  // directives.
1713  if (VD && !DSAStack->isClauseParsingMode()) {
1714    if (const auto *RD = VD->getType()
1715                             .getCanonicalType()
1716                             .getNonReferenceType()
1717                             ->getAsCXXRecordDecl()) {
1718      bool SavedForceCaptureByReferenceInTargetExecutable =
1719          DSAStack->isForceCaptureByReferenceInTargetExecutable();
1720      DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true);
1721      if (RD->isLambda()) {
1722        llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
1723        FieldDecl *ThisCapture;
1724        RD->getCaptureFields(Captures, ThisCapture);
1725        for (const LambdaCapture &LC : RD->captures()) {
1726          if (LC.getCaptureKind() == LCK_ByRef) {
1727            VarDecl *VD = LC.getCapturedVar();
1728            DeclContext *VDC = VD->getDeclContext();
1729            if (!VDC->Encloses(CurContext))
1730              continue;
1731            DSAStackTy::DSAVarData DVarPrivate =
1732                DSAStack->getTopDSA(VD, /*FromParent=*/false);
1733            // Do not capture already captured variables.
1734            if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
1735                DVarPrivate.CKind == OMPC_unknown &&
1736                !DSAStack->checkMappableExprComponentListsForDecl(
1737                    D, /*CurrentRegionOnly=*/true,
1738                    [](OMPClauseMappableExprCommon::
1739                           MappableExprComponentListRef,
1740                       OpenMPClauseKind) { return true; }))
1741              MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar());
1742          } else if (LC.getCaptureKind() == LCK_This) {
1743            QualType ThisTy = getCurrentThisType();
1744            if (!ThisTy.isNull() &&
1745                Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
1746              CheckCXXThisCapture(LC.getLocation());
1747          }
1748        }
1749      }
1750      DSAStack->setForceCaptureByReferenceInTargetExecutable(
1751          SavedForceCaptureByReferenceInTargetExecutable);
1752    }
1753  }
1754
1755  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1756      (!DSAStack->isClauseParsingMode() ||
1757       DSAStack->getParentDirective() != OMPD_unknown)) {
1758    auto &&Info = DSAStack->isLoopControlVariable(D);
1759    if (Info.first ||
1760        (VD && VD->hasLocalStorage() &&
1761         isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
1762        (VD && DSAStack->isForceVarCapturing()))
1763      return VD ? VD : Info.second;
1764    DSAStackTy::DSAVarData DVarPrivate =
1765        DSAStack->getTopDSA(DDSAStack->isClauseParsingMode());
1766    if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1767      return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1768    DVarPrivate = DSAStack->hasDSA(DisOpenMPPrivate,
1769                                   [](OpenMPDirectiveKind) { return true; },
1770                                   DSAStack->isClauseParsingMode());
1771    if (DVarPrivate.CKind != OMPC_unknown)
1772      return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1773  }
1774  return nullptr;
1775}
1776
1777void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1778                                        unsigned Levelconst {
1779  SmallVector<OpenMPDirectiveKind4Regions;
1780  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1781  FunctionScopesIndex -= Regions.size();
1782}
1783
1784void Sema::startOpenMPLoop() {
1785   (0) . __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1785, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LangOpts.OpenMP && "OpenMP must be enabled.");
1786  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
1787    DSAStack->loopInit();
1788}
1789
1790bool Sema::isOpenMPPrivateDecl(const ValueDecl *Dunsigned Levelconst {
1791   (0) . __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1791, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LangOpts.OpenMP && "OpenMP is not allowed");
1792  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
1793    if (DSAStack->getAssociatedLoops() > 0 &&
1794        !DSAStack->isLoopStarted()) {
1795      DSAStack->resetPossibleLoopCounter(D);
1796      DSAStack->loopStart();
1797      return true;
1798    }
1799    if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
1800         DSAStack->isLoopControlVariable(D).first) &&
1801        !DSAStack->hasExplicitDSA(
1802            D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
1803        !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
1804      return true;
1805  }
1806  return DSAStack->hasExplicitDSA(
1807             D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
1808         (DSAStack->isClauseParsingMode() &&
1809          DSAStack->getClauseParsingMode() == OMPC_private) ||
1810         // Consider taskgroup reduction descriptor variable a private to avoid
1811         // possible capture in the region.
1812         (DSAStack->hasExplicitDirective(
1813              [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1814              Level) &&
1815          DSAStack->isTaskgroupReductionRef(DLevel));
1816}
1817
1818void Sema::setOpenMPCaptureKind(FieldDecl *FDconst ValueDecl *D,
1819                                unsigned Level) {
1820   (0) . __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1820, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LangOpts.OpenMP && "OpenMP is not allowed");
1821  D = getCanonicalDecl(D);
1822  OpenMPClauseKind OMPC = OMPC_unknown;
1823  for (unsigned I = DSAStack->getNestingLevel() + 1I > Level; --I) {
1824    const unsigned NewLevel = I - 1;
1825    if (DSAStack->hasExplicitDSA(D,
1826                                 [&OMPC](const OpenMPClauseKind K) {
1827                                   if (isOpenMPPrivate(K)) {
1828                                     OMPC = K;
1829                                     return true;
1830                                   }
1831                                   return false;
1832                                 },
1833                                 NewLevel))
1834      break;
1835    if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1836            DNewLevel,
1837            [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
1838               OpenMPClauseKind) { return true; })) {
1839      OMPC = OMPC_map;
1840      break;
1841    }
1842    if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1843                                       NewLevel)) {
1844      OMPC = OMPC_map;
1845      if (D->getType()->isScalarType() &&
1846          DSAStack->getDefaultDMAAtLevel(NewLevel) !=
1847              DefaultMapAttributes::DMA_tofrom_scalar)
1848        OMPC = OMPC_firstprivate;
1849      break;
1850    }
1851  }
1852  if (OMPC != OMPC_unknown)
1853    FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1854}
1855
1856bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D,
1857                                      unsigned Levelconst {
1858   (0) . __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 1858, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LangOpts.OpenMP && "OpenMP is not allowed");
1859  // Return true if the current level is no longer enclosed in a target region.
1860
1861  const auto *VD = dyn_cast<VarDecl>(D);
1862  return VD && !VD->hasLocalStorage() &&
1863         DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1864                                        Level);
1865}
1866
1867void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1868
1869void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
1870                               const DeclarationNameInfo &DirName,
1871                               Scope *CurScopeSourceLocation Loc) {
1872  DSAStack->push(DKindDirNameCurScopeLoc);
1873  PushExpressionEvaluationContext(
1874      ExpressionEvaluationContext::PotentiallyEvaluated);
1875}
1876
1877void Sema::StartOpenMPClause(OpenMPClauseKind K) {
1878  DSAStack->setClauseParsingMode(K);
1879}
1880
1881void Sema::EndOpenMPClause() {
1882  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1883}
1884
1885void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1886  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1887  //  A variable of class type (or array thereof) that appears in a lastprivate
1888  //  clause requires an accessible, unambiguous default constructor for the
1889  //  class type, unless the list item is also specified in a firstprivate
1890  //  clause.
1891  if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1892    for (OMPClause *C : D->clauses()) {
1893      if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1894        SmallVector<Expr *, 8> PrivateCopies;
1895        for (Expr *DE : Clause->varlists()) {
1896          if (DE->isValueDependent() || DE->isTypeDependent()) {
1897            PrivateCopies.push_back(nullptr);
1898            continue;
1899          }
1900          auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1901          auto *VD = cast<VarDecl>(DRE->getDecl());
1902          QualType Type = VD->getType().getNonReferenceType();
1903          const DSAStackTy::DSAVarData DVar =
1904              DSAStack->getTopDSA(VD, /*FromParent=*/false);
1905          if (DVar.CKind == OMPC_lastprivate) {
1906            // Generate helper private variable and initialize it with the
1907            // default value. The address of the original variable is replaced
1908            // by the address of the new private variable in CodeGen. This new
1909            // variable is not added to IdResolver, so the code in the OpenMP
1910            // region uses original variable for proper diagnostics.
1911            VarDecl *VDPrivate = buildVarDecl(
1912                *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1913                VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
1914            ActOnUninitializedDecl(VDPrivate);
1915            if (VDPrivate->isInvalidDecl())
1916              continue;
1917            PrivateCopies.push_back(buildDeclRefExpr(
1918                *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1919          } else {
1920            // The variable is also a firstprivate, so initialization sequence
1921            // for private copy is generated already.
1922            PrivateCopies.push_back(nullptr);
1923          }
1924        }
1925        // Set initializers to private copies if no errors were found.
1926        if (PrivateCopies.size() == Clause->varlist_size())
1927          Clause->setPrivateCopies(PrivateCopies);
1928      }
1929    }
1930  }
1931
1932  DSAStack->pop();
1933  DiscardCleanupsInEvaluationContext();
1934  PopExpressionEvaluationContext();
1935}
1936
1937static bool FinishOpenMPLinearClause(OMPLinearClause &ClauseDeclRefExpr *IV,
1938                                     Expr *NumIterationsSema &SemaRef,
1939                                     Scope *SDSAStackTy *Stack);
1940
1941namespace {
1942
1943class VarDeclFilterCCC final : public CorrectionCandidateCallback {
1944private:
1945  Sema &SemaRef;
1946
1947public:
1948  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1949  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1950    NamedDecl *ND = Candidate.getCorrectionDecl();
1951    if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1952      return VD->hasGlobalStorage() &&
1953             SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1954                                   SemaRef.getCurScope());
1955    }
1956    return false;
1957  }
1958
1959  std::unique_ptr<CorrectionCandidateCallbackclone() override {
1960    return llvm::make_unique<VarDeclFilterCCC>(*this);
1961  }
1962
1963};
1964
1965class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
1966private:
1967  Sema &SemaRef;
1968
1969public:
1970  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1971  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1972    NamedDecl *ND = Candidate.getCorrectionDecl();
1973    if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
1974               isa<FunctionDecl>(ND))) {
1975      return SemaRef.isDeclInScope(NDSemaRef.getCurLexicalContext(),
1976                                   SemaRef.getCurScope());
1977    }
1978    return false;
1979  }
1980
1981  std::unique_ptr<CorrectionCandidateCallbackclone() override {
1982    return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this);
1983  }
1984};
1985
1986// namespace
1987
1988ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
1989                                         CXXScopeSpec &ScopeSpec,
1990                                         const DeclarationNameInfo &Id,
1991                                         OpenMPDirectiveKind Kind) {
1992  LookupResult Lookup(*thisIdLookupOrdinaryName);
1993  LookupParsedName(LookupCurScope, &ScopeSpectrue);
1994
1995  if (Lookup.isAmbiguous())
1996    return ExprError();
1997
1998  VarDecl *VD;
1999  if (!Lookup.isSingleResult()) {
2000    VarDeclFilterCCC CCC(*this);
2001    if (TypoCorrection Corrected =
2002            CorrectTypo(IdLookupOrdinaryNameCurScopenullptrCCC,
2003                        CTK_ErrorRecovery)) {
2004      diagnoseTypo(Corrected,
2005                   PDiag(Lookup.empty()
2006                             ? diag::err_undeclared_var_use_suggest
2007                             : diag::err_omp_expected_var_arg_suggest)
2008                       << Id.getName());
2009      VD = Corrected.getCorrectionDeclAs<VarDecl>();
2010    } else {
2011      Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2012                                       : diag::err_omp_expected_var_arg)
2013          << Id.getName();
2014      return ExprError();
2015    }
2016  } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2017    Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2018    Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2019    return ExprError();
2020  }
2021  Lookup.suppressDiagnostics();
2022
2023  // OpenMP [2.9.2, Syntax, C/C++]
2024  //   Variables must be file-scope, namespace-scope, or static block-scope.
2025  if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2026    Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2027        << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2028    bool IsDecl =
2029        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2030    Diag(VD->getLocation(),
2031         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2032        << VD;
2033    return ExprError();
2034  }
2035
2036  VarDecl *CanonicalVD = VD->getCanonicalDecl();
2037  NamedDecl *ND = CanonicalVD;
2038  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2039  //   A threadprivate directive for file-scope variables must appear outside
2040  //   any definition or declaration.
2041  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2042      !getCurLexicalContext()->isTranslationUnit()) {
2043    Diag(Id.getLoc(), diag::err_omp_var_scope)
2044        << getOpenMPDirectiveName(Kind) << VD;
2045    bool IsDecl =
2046        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2047    Diag(VD->getLocation(),
2048         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2049        << VD;
2050    return ExprError();
2051  }
2052  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2053  //   A threadprivate directive for static class member variables must appear
2054  //   in the class definition, in the same scope in which the member
2055  //   variables are declared.
2056  if (CanonicalVD->isStaticDataMember() &&
2057      !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2058    Diag(Id.getLoc(), diag::err_omp_var_scope)
2059        << getOpenMPDirectiveName(Kind) << VD;
2060    bool IsDecl =
2061        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2062    Diag(VD->getLocation(),
2063         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2064        << VD;
2065    return ExprError();
2066  }
2067  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2068  //   A threadprivate directive for namespace-scope variables must appear
2069  //   outside any definition or declaration other than the namespace
2070  //   definition itself.
2071  if (CanonicalVD->getDeclContext()->isNamespace() &&
2072      (!getCurLexicalContext()->isFileContext() ||
2073       !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2074    Diag(Id.getLoc(), diag::err_omp_var_scope)
2075        << getOpenMPDirectiveName(Kind) << VD;
2076    bool IsDecl =
2077        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2078    Diag(VD->getLocation(),
2079         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2080        << VD;
2081    return ExprError();
2082  }
2083  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2084  //   A threadprivate directive for static block-scope variables must appear
2085  //   in the scope of the variable and not in a nested scope.
2086  if (CanonicalVD->isLocalVarDecl() && CurScope &&
2087      !isDeclInScope(NDgetCurLexicalContext(), CurScope)) {
2088    Diag(Id.getLoc(), diag::err_omp_var_scope)
2089        << getOpenMPDirectiveName(Kind) << VD;
2090    bool IsDecl =
2091        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2092    Diag(VD->getLocation(),
2093         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2094        << VD;
2095    return ExprError();
2096  }
2097
2098  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2099  //   A threadprivate directive must lexically precede all references to any
2100  //   of the variables in its list.
2101  if (Kind == OMPD_threadprivate && VD->isUsed() &&
2102      !DSAStack->isThreadPrivate(VD)) {
2103    Diag(Id.getLoc(), diag::err_omp_var_used)
2104        << getOpenMPDirectiveName(Kind) << VD;
2105    return ExprError();
2106  }
2107
2108  QualType ExprType = VD->getType().getNonReferenceType();
2109  return DeclRefExpr::Create(ContextNestedNameSpecifierLoc(),
2110                             SourceLocation(), VD,
2111                             /*RefersToEnclosingVariableOrCapture=*/false,
2112                             Id.getLoc(), ExprTypeVK_LValue);
2113}
2114
2115Sema::DeclGroupPtrTy
2116Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2117                                        ArrayRef<Expr *> VarList) {
2118  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2119    CurContext->addDecl(D);
2120    return DeclGroupPtrTy::make(DeclGroupRef(D));
2121  }
2122  return nullptr;
2123}
2124
2125namespace {
2126class LocalVarRefChecker final
2127    : public ConstStmtVisitor<LocalVarRefCheckerbool> {
2128  Sema &SemaRef;
2129
2130public:
2131  bool VisitDeclRefExpr(const DeclRefExpr *E) {
2132    if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2133      if (VD->hasLocalStorage()) {
2134        SemaRef.Diag(E->getBeginLoc(),
2135                     diag::err_omp_local_var_in_threadprivate_init)
2136            << E->getSourceRange();
2137        SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2138            << VD << VD->getSourceRange();
2139        return true;
2140      }
2141    }
2142    return false;
2143  }
2144  bool VisitStmt(const Stmt *S) {
2145    for (const Stmt *Child : S->children()) {
2146      if (Child && Visit(Child))
2147        return true;
2148    }
2149    return false;
2150  }
2151  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2152};
2153// namespace
2154
2155OMPThreadPrivateDecl *
2156Sema::CheckOMPThreadPrivateDecl(SourceLocation LocArrayRef<Expr *> VarList) {
2157  SmallVector<Expr *, 8Vars;
2158  for (Expr *RefExpr : VarList) {
2159    auto *DE = cast<DeclRefExpr>(RefExpr);
2160    auto *VD = cast<VarDecl>(DE->getDecl());
2161    SourceLocation ILoc = DE->getExprLoc();
2162
2163    // Mark variable as used.
2164    VD->setReferenced();
2165    VD->markUsed(Context);
2166
2167    QualType QType = VD->getType();
2168    if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2169      // It will be analyzed later.
2170      Vars.push_back(DE);
2171      continue;
2172    }
2173
2174    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2175    //   A threadprivate variable must not have an incomplete type.
2176    if (RequireCompleteType(ILoc, VD->getType(),
2177                            diag::err_omp_threadprivate_incomplete_type)) {
2178      continue;
2179    }
2180
2181    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2182    //   A threadprivate variable must not have a reference type.
2183    if (VD->getType()->isReferenceType()) {
2184      Diag(ILoc, diag::err_omp_ref_type_arg)
2185          << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2186      bool IsDecl =
2187          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2188      Diag(VD->getLocation(),
2189           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2190          << VD;
2191      continue;
2192    }
2193
2194    // Check if this is a TLS variable. If TLS is not being supported, produce
2195    // the corresponding diagnostic.
2196    if ((VD->getTLSKind() != VarDecl::TLS_None &&
2197         !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2198           getLangOpts().OpenMPUseTLS &&
2199           getASTContext().getTargetInfo().isTLSSupported())) ||
2200        (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2201         !VD->isLocalVarDecl())) {
2202      Diag(ILoc, diag::err_omp_var_thread_local)
2203          << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2204      bool IsDecl =
2205          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2206      Diag(VD->getLocation(),
2207           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2208          << VD;
2209      continue;
2210    }
2211
2212    // Check if initial value of threadprivate variable reference variable with
2213    // local storage (it is not supported by runtime).
2214    if (const Expr *Init = VD->getAnyInitializer()) {
2215      LocalVarRefChecker Checker(*this);
2216      if (Checker.Visit(Init))
2217        continue;
2218    }
2219
2220    Vars.push_back(RefExpr);
2221    DSAStack->addDSA(VD, DE, OMPC_threadprivate);
2222    VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2223        Context, SourceRange(Loc, Loc)));
2224    if (ASTMutationListener *ML = Context.getASTMutationListener())
2225      ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2226  }
2227  OMPThreadPrivateDecl *D = nullptr;
2228  if (!Vars.empty()) {
2229    D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2230                                     Vars);
2231    D->setAccess(AS_public);
2232  }
2233  return D;
2234}
2235
2236static OMPAllocateDeclAttr::AllocatorTypeTy
2237getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2238  if (!Allocator)
2239    return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2240  if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2241      Allocator->isInstantiationDependent() ||
2242      Allocator->containsUnexpandedParameterPack())
2243    return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2244  auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2245  for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2246       I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2247    auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
2248    Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2249    const Expr *AE = Allocator->IgnoreParenImpCasts();
2250    llvm::FoldingSetNodeID AEId, DAEId;
2251    AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2252    DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2253    if (AEId == DAEId) {
2254      AllocatorKindRes = AllocatorKind;
2255      break;
2256    }
2257  }
2258  return AllocatorKindRes;
2259}
2260
2261Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
2262    SourceLocation LocArrayRef<Expr *> VarList,
2263    ArrayRef<OMPClause *> ClausesDeclContext *Owner) {
2264   (0) . __assert_fail ("Clauses.size() <= 1 && \"Expected at most one clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 2264, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Clauses.size() <= 1 && "Expected at most one clause.");
2265  Expr *Allocator = nullptr;
2266  if (Clauses.empty()) {
2267    // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
2268    // allocate directives that appear in a target region must specify an
2269    // allocator clause unless a requires directive with the dynamic_allocators
2270    // clause is present in the same compilation unit.
2271    if (LangOpts.OpenMPIsDevice &&
2272        !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
2273      targetDiag(Loc, diag::err_expected_allocator_clause);
2274  } else {
2275    Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
2276  }
2277  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
2278      getAllocatorKind(*thisDSAStack, Allocator);
2279  SmallVector<Expr *, 8Vars;
2280  for (Expr *RefExpr : VarList) {
2281    auto *DE = cast<DeclRefExpr>(RefExpr);
2282    auto *VD = cast<VarDecl>(DE->getDecl());
2283
2284    // Check if this is a TLS variable or global register.
2285    if (VD->getTLSKind() != VarDecl::TLS_None ||
2286        VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
2287        (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2288         !VD->isLocalVarDecl()))
2289      continue;
2290    // Do not apply for parameters.
2291    if (isa<ParmVarDecl>(VD))
2292      continue;
2293
2294    // If the used several times in the allocate directive, the same allocator
2295    // must be used.
2296    if (VD->hasAttr<OMPAllocateDeclAttr>()) {
2297      const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2298      Expr *PrevAllocator = A->getAllocator();
2299      OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2300          getAllocatorKind(*thisDSAStack, PrevAllocator);
2301      bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2302      if (AllocatorsMatch && Allocator && PrevAllocator) {
2303        const Expr *AE = Allocator->IgnoreParenImpCasts();
2304        const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
2305        llvm::FoldingSetNodeID AEId, PAEId;
2306        AE->Profile(AEId, Context, /*Canonical=*/true);
2307        PAE->Profile(PAEId, Context, /*Canonical=*/true);
2308        AllocatorsMatch = AEId == PAEId;
2309      }
2310      if (!AllocatorsMatch) {
2311        SmallString<256> AllocatorBuffer;
2312        llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
2313        if (Allocator)
2314          Allocator->printPretty(AllocatorStream, nullptr, getPrintingPolicy());
2315        SmallString<256> PrevAllocatorBuffer;
2316        llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
2317        if (PrevAllocator)
2318          PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
2319                                     getPrintingPolicy());
2320
2321        SourceLocation AllocatorLoc =
2322            Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
2323        SourceRange AllocatorRange =
2324            Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
2325        SourceLocation PrevAllocatorLoc =
2326            PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
2327        SourceRange PrevAllocatorRange =
2328            PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
2329        Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
2330            << (Allocator ? 1 : 0) << AllocatorStream.str()
2331            << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
2332            << AllocatorRange;
2333        Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
2334            << PrevAllocatorRange;
2335        continue;
2336      }
2337    }
2338
2339    // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
2340    // If a list item has a static storage type, the allocator expression in the
2341    // allocator clause must be a constant expression that evaluates to one of
2342    // the predefined memory allocator values.
2343    if (Allocator && VD->hasGlobalStorage()) {
2344      if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
2345        Diag(Allocator->getExprLoc(),
2346             diag::err_omp_expected_predefined_allocator)
2347            << Allocator->getSourceRange();
2348        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
2349                      VarDecl::DeclarationOnly;
2350        Diag(VD->getLocation(),
2351             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2352            << VD;
2353        continue;
2354      }
2355    }
2356
2357    Vars.push_back(RefExpr);
2358    if ((!Allocator || (Allocator && !Allocator->isTypeDependent() &&
2359                        !Allocator->isValueDependent() &&
2360                        !Allocator->isInstantiationDependent() &&
2361                        !Allocator->containsUnexpandedParameterPack())) &&
2362        !VD->hasAttr<OMPAllocateDeclAttr>()) {
2363      Attr *A = OMPAllocateDeclAttr::CreateImplicit(
2364          Context, AllocatorKind, Allocator, DE->getSourceRange());
2365      VD->addAttr(A);
2366      if (ASTMutationListener *ML = Context.getASTMutationListener())
2367        ML->DeclarationMarkedOpenMPAllocate(VD, A);
2368    }
2369  }
2370  if (Vars.empty())
2371    return nullptr;
2372  if (!Owner)
2373    Owner = getCurLexicalContext();
2374  OMPAllocateDecl *D =
2375      OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
2376  D->setAccess(AS_public);
2377  Owner->addDecl(D);
2378  return DeclGroupPtrTy::make(DeclGroupRef(D));
2379}
2380
2381Sema::DeclGroupPtrTy
2382Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
2383                                   ArrayRef<OMPClause *> ClauseList) {
2384  OMPRequiresDecl *D = nullptr;
2385  if (!CurContext->isFileContext()) {
2386    Diag(Loc, diag::err_omp_invalid_scope) << "requires";
2387  } else {
2388    D = CheckOMPRequiresDecl(Loc, ClauseList);
2389    if (D) {
2390      CurContext->addDecl(D);
2391      DSAStack->addRequiresDecl(D);
2392    }
2393  }
2394  return DeclGroupPtrTy::make(DeclGroupRef(D));
2395}
2396
2397OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
2398                                            ArrayRef<OMPClause *> ClauseList) {
2399  if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
2400    return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
2401                                   ClauseList);
2402  return nullptr;
2403}
2404
2405static void reportOriginalDsa(Sema &SemaRefconst DSAStackTy *Stack,
2406                              const ValueDecl *D,
2407                              const DSAStackTy::DSAVarData &DVar,
2408                              bool IsLoopIterVar = false) {
2409  if (DVar.RefExpr) {
2410    SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2411        << getOpenMPClauseName(DVar.CKind);
2412    return;
2413  }
2414  enum {
2415    PDSA_StaticMemberShared,
2416    PDSA_StaticLocalVarShared,
2417    PDSA_LoopIterVarPrivate,
2418    PDSA_LoopIterVarLinear,
2419    PDSA_LoopIterVarLastprivate,
2420    PDSA_ConstVarShared,
2421    PDSA_GlobalVarShared,
2422    PDSA_TaskVarFirstprivate,
2423    PDSA_LocalVarPrivate,
2424    PDSA_Implicit
2425  } Reason = PDSA_Implicit;
2426  bool ReportHint = false;
2427  auto ReportLoc = D->getLocation();
2428  auto *VD = dyn_cast<VarDecl>(D);
2429  if (IsLoopIterVar) {
2430    if (DVar.CKind == OMPC_private)
2431      Reason = PDSA_LoopIterVarPrivate;
2432    else if (DVar.CKind == OMPC_lastprivate)
2433      Reason = PDSA_LoopIterVarLastprivate;
2434    else
2435      Reason = PDSA_LoopIterVarLinear;
2436  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
2437             DVar.CKind == OMPC_firstprivate) {
2438    Reason = PDSA_TaskVarFirstprivate;
2439    ReportLoc = DVar.ImplicitDSALoc;
2440  } else if (VD && VD->isStaticLocal())
2441    Reason = PDSA_StaticLocalVarShared;
2442  else if (VD && VD->isStaticDataMember())
2443    Reason = PDSA_StaticMemberShared;
2444  else if (VD && VD->isFileVarDecl())
2445    Reason = PDSA_GlobalVarShared;
2446  else if (D->getType().isConstant(SemaRef.getASTContext()))
2447    Reason = PDSA_ConstVarShared;
2448  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2449    ReportHint = true;
2450    Reason = PDSA_LocalVarPrivate;
2451  }
2452  if (Reason != PDSA_Implicit) {
2453    SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2454        << Reason << ReportHint
2455        << getOpenMPDirectiveName(Stack->getCurrentDirective());
2456  } else if (DVar.ImplicitDSALoc.isValid()) {
2457    SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2458        << getOpenMPClauseName(DVar.CKind);
2459  }
2460}
2461
2462namespace {
2463class DSAAttrChecker final : public StmtVisitor<DSAAttrCheckervoid> {
2464  DSAStackTy *Stack;
2465  Sema &SemaRef;
2466  bool ErrorFound = false;
2467  CapturedStmt *CS = nullptr;
2468  llvm::SmallVector<Expr *, 4ImplicitFirstprivate;
2469  llvm::SmallVector<Expr *, 4ImplicitMap;
2470  Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2471  llvm::SmallDenseSet<const ValueDecl *, 4ImplicitDeclarations;
2472
2473  void VisitSubCaptures(OMPExecutableDirective *S) {
2474    // Check implicitly captured variables.
2475    if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
2476      return;
2477    for (const CapturedStmt::Capture &Cap :
2478         S->getInnermostCapturedStmt()->captures()) {
2479      if (!Cap.capturesVariable())
2480        continue;
2481      VarDecl *VD = Cap.getCapturedVar();
2482      // Do not try to map the variable if it or its sub-component was mapped
2483      // already.
2484      if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
2485          Stack->checkMappableExprComponentListsForDecl(
2486              VD, /*CurrentRegionOnly=*/true,
2487              [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2488                 OpenMPClauseKind) { return true; }))
2489        continue;
2490      DeclRefExpr *DRE = buildDeclRefExpr(
2491          SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
2492          Cap.getLocation(), /*RefersToCapture=*/true);
2493      Visit(DRE);
2494    }
2495  }
2496
2497public:
2498  void VisitDeclRefExpr(DeclRefExpr *E) {
2499    if (E->isTypeDependent() || E->isValueDependent() ||
2500        E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2501      return;
2502    if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2503      VD = VD->getCanonicalDecl();
2504      // Skip internally declared variables.
2505      if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
2506        return;
2507
2508      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
2509      // Check if the variable has explicit DSA set and stop analysis if it so.
2510      if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2511        return;
2512
2513      // Skip internally declared static variables.
2514      llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
2515          OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2516      if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) &&
2517          (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2518        return;
2519
2520      SourceLocation ELoc = E->getExprLoc();
2521      OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2522      // The default(none) clause requires that each variable that is referenced
2523      // in the construct, and does not have a predetermined data-sharing
2524      // attribute, must have its data-sharing attribute explicitly determined
2525      // by being listed in a data-sharing attribute clause.
2526      if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2527          isImplicitOrExplicitTaskingRegion(DKind) &&
2528          VarsWithInheritedDSA.count(VD) == 0) {
2529        VarsWithInheritedDSA[VD] = E;
2530        return;
2531      }
2532
2533      if (isOpenMPTargetExecutionDirective(DKind) &&
2534          !Stack->isLoopControlVariable(VD).first) {
2535        if (!Stack->checkMappableExprComponentListsForDecl(
2536                VD, /*CurrentRegionOnly=*/true,
2537                [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2538                       StackComponents,
2539                   OpenMPClauseKind) {
2540                  // Variable is used if it has been marked as an array, array
2541                  // section or the variable iself.
2542                  return StackComponents.size() == 1 ||
2543                         std::all_of(
2544                             std::next(StackComponents.rbegin()),
2545                             StackComponents.rend(),
2546                             [](const OMPClauseMappableExprCommon::
2547                                    MappableComponent &MC) {
2548                               return MC.getAssociatedDeclaration() ==
2549                                          nullptr &&
2550                                      (isa<OMPArraySectionExpr>(
2551                                           MC.getAssociatedExpression()) ||
2552                                       isa<ArraySubscriptExpr>(
2553                                           MC.getAssociatedExpression()));
2554                             });
2555                })) {
2556          bool IsFirstprivate = false;
2557          // By default lambdas are captured as firstprivates.
2558          if (const auto *RD =
2559                  VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2560            IsFirstprivate = RD->isLambda();
2561          IsFirstprivate =
2562              IsFirstprivate ||
2563              (VD->getType().getNonReferenceType()->isScalarType() &&
2564               Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2565          if (IsFirstprivate)
2566            ImplicitFirstprivate.emplace_back(E);
2567          else
2568            ImplicitMap.emplace_back(E);
2569          return;
2570        }
2571      }
2572
2573      // OpenMP [2.9.3.6, Restrictions, p.2]
2574      //  A list item that appears in a reduction clause of the innermost
2575      //  enclosing worksharing or parallel construct may not be accessed in an
2576      //  explicit task.
2577      DVar = Stack->hasInnermostDSA(
2578          VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2579          [](OpenMPDirectiveKind K) {
2580            return isOpenMPParallelDirective(K) ||
2581                   isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2582          },
2583          /*FromParent=*/true);
2584      if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2585        ErrorFound = true;
2586        SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2587        reportOriginalDsa(SemaRef, Stack, VD, DVar);
2588        return;
2589      }
2590
2591      // Define implicit data-sharing attributes for task.
2592      DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
2593      if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2594          !Stack->isLoopControlVariable(VD).first) {
2595        ImplicitFirstprivate.push_back(E);
2596        return;
2597      }
2598
2599      // Store implicitly used globals with declare target link for parent
2600      // target.
2601      if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
2602          *Res == OMPDeclareTargetDeclAttr::MT_Link) {
2603        Stack->addToParentTargetRegionLinkGlobals(E);
2604        return;
2605      }
2606    }
2607  }
2608  void VisitMemberExpr(MemberExpr *E) {
2609    if (E->isTypeDependent() || E->isValueDependent() ||
2610        E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2611      return;
2612    auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
2613    OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2614    if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) {
2615      if (!FD)
2616        return;
2617      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
2618      // Check if the variable has explicit DSA set and stop analysis if it
2619      // so.
2620      if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2621        return;
2622
2623      if (isOpenMPTargetExecutionDirective(DKind) &&
2624          !Stack->isLoopControlVariable(FD).first &&
2625          !Stack->checkMappableExprComponentListsForDecl(
2626              FD, /*CurrentRegionOnly=*/true,
2627              [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2628                     StackComponents,
2629                 OpenMPClauseKind) {
2630                return isa<CXXThisExpr>(
2631                    cast<MemberExpr>(
2632                        StackComponents.back().getAssociatedExpression())
2633                        ->getBase()
2634                        ->IgnoreParens());
2635              })) {
2636        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
2637        //  A bit-field cannot appear in a map clause.
2638        //
2639        if (FD->isBitField())
2640          return;
2641
2642        // Check to see if the member expression is referencing a class that
2643        // has already been explicitly mapped
2644        if (Stack->isClassPreviouslyMapped(TE->getType()))
2645          return;
2646
2647        ImplicitMap.emplace_back(E);
2648        return;
2649      }
2650
2651      SourceLocation ELoc = E->getExprLoc();
2652      // OpenMP [2.9.3.6, Restrictions, p.2]
2653      //  A list item that appears in a reduction clause of the innermost
2654      //  enclosing worksharing or parallel construct may not be accessed in
2655      //  an  explicit task.
2656      DVar = Stack->hasInnermostDSA(
2657          FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2658          [](OpenMPDirectiveKind K) {
2659            return isOpenMPParallelDirective(K) ||
2660                   isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2661          },
2662          /*FromParent=*/true);
2663      if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2664        ErrorFound = true;
2665        SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2666        reportOriginalDsa(SemaRef, Stack, FD, DVar);
2667        return;
2668      }
2669
2670      // Define implicit data-sharing attributes for task.
2671      DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
2672      if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2673          !Stack->isLoopControlVariable(FD).first) {
2674        // Check if there is a captured expression for the current field in the
2675        // region. Do not mark it as firstprivate unless there is no captured
2676        // expression.
2677        // TODO: try to make it firstprivate.
2678        if (DVar.CKind != OMPC_unknown)
2679          ImplicitFirstprivate.push_back(E);
2680      }
2681      return;
2682    }
2683    if (isOpenMPTargetExecutionDirective(DKind)) {
2684      OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
2685      if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2686                                        /*NoDiagnose=*/true))
2687        return;
2688      const auto *VD = cast<ValueDecl>(
2689          CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2690      if (!Stack->checkMappableExprComponentListsForDecl(
2691              VD, /*CurrentRegionOnly=*/true,
2692              [&CurComponents](
2693                  OMPClauseMappableExprCommon::MappableExprComponentListRef
2694                      StackComponents,
2695                  OpenMPClauseKind) {
2696                auto CCI = CurComponents.rbegin();
2697                auto CCE = CurComponents.rend();
2698                for (const auto &SC : llvm::reverse(StackComponents)) {
2699                  // Do both expressions have the same kind?
2700                  if (CCI->getAssociatedExpression()->getStmtClass() !=
2701                      SC.getAssociatedExpression()->getStmtClass())
2702                    if (!(isa<OMPArraySectionExpr>(
2703                              SC.getAssociatedExpression()) &&
2704                          isa<ArraySubscriptExpr>(
2705                              CCI->getAssociatedExpression())))
2706                      return false;
2707
2708                  const Decl *CCD = CCI->getAssociatedDeclaration();
2709                  const Decl *SCD = SC.getAssociatedDeclaration();
2710                  CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2711                  SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2712                  if (SCD != CCD)
2713                    return false;
2714                  std::advance(CCI, 1);
2715                  if (CCI == CCE)
2716                    break;
2717                }
2718                return true;
2719              })) {
2720        Visit(E->getBase());
2721      }
2722    } else {
2723      Visit(E->getBase());
2724    }
2725  }
2726  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2727    for (OMPClause *C : S->clauses()) {
2728      // Skip analysis of arguments of implicitly defined firstprivate clause
2729      // for task|target directives.
2730      // Skip analysis of arguments of implicitly defined map clause for target
2731      // directives.
2732      if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2733                 C->isImplicit())) {
2734        for (Stmt *CC : C->children()) {
2735          if (CC)
2736            Visit(CC);
2737        }
2738      }
2739    }
2740    // Check implicitly captured variables.
2741    VisitSubCaptures(S);
2742  }
2743  void VisitStmt(Stmt *S) {
2744    for (Stmt *C : S->children()) {
2745      if (C) {
2746        // Check implicitly captured variables in the task-based directives to
2747        // check if they must be firstprivatized.
2748        Visit(C);
2749      }
2750    }
2751  }
2752
2753  bool isErrorFound() const { return ErrorFound; }
2754  ArrayRef<Expr *> getImplicitFirstprivate() const {
2755    return ImplicitFirstprivate;
2756  }
2757  ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2758  const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
2759    return VarsWithInheritedDSA;
2760  }
2761
2762  DSAAttrChecker(DSAStackTy *SSema &SemaRefCapturedStmt *CS)
2763      : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
2764    // Process declare target link variables for the target directives.
2765    if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
2766      for (DeclRefExpr *E : Stack->getLinkGlobals())
2767        Visit(E);
2768    }
2769  }
2770};
2771// namespace
2772
2773void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKindScope *CurScope) {
2774  switch (DKind) {
2775  case OMPD_parallel:
2776  case OMPD_parallel_for:
2777  case OMPD_parallel_for_simd:
2778  case OMPD_parallel_sections:
2779  case OMPD_teams:
2780  case OMPD_teams_distribute:
2781  case OMPD_teams_distribute_simd: {
2782    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(321).withConst();
2783    QualType KmpInt32PtrTy =
2784        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2785    Sema::CapturedParamNameType Params[] = {
2786        std::make_pair(".global_tid."KmpInt32PtrTy),
2787        std::make_pair(".bound_tid."KmpInt32PtrTy),
2788        std::make_pair(StringRef(), QualType()) // __context with shared vars
2789    };
2790    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2791                             Params);
2792    break;
2793  }
2794  case OMPD_target_teams:
2795  case OMPD_target_parallel:
2796  case OMPD_target_parallel_for:
2797  case OMPD_target_parallel_for_simd:
2798  case OMPD_target_teams_distribute:
2799  case OMPD_target_teams_distribute_simd: {
2800    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(321).withConst();
2801    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2802    QualType KmpInt32PtrTy =
2803        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2804    QualType Args[] = {VoidPtrTy};
2805    FunctionProtoType::ExtProtoInfo EPI;
2806    EPI.Variadic = true;
2807    QualType CopyFnType = Context.getFunctionType(Context.VoidTyArgsEPI);
2808    Sema::CapturedParamNameType Params[] = {
2809        std::make_pair(".global_tid."KmpInt32Ty),
2810        std::make_pair(".part_id."KmpInt32PtrTy),
2811        std::make_pair(".privates."VoidPtrTy),
2812        std::make_pair(
2813            ".copy_fn.",
2814            Context.getPointerType(CopyFnType).withConst().withRestrict()),
2815        std::make_pair(".task_t."Context.VoidPtrTy.withConst()),
2816        std::make_pair(StringRef(), QualType()) // __context with shared vars
2817    };
2818    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2819                             Params);
2820    // Mark this captured region as inlined, because we don't use outlined
2821    // function directly.
2822    getCurCapturedRegion()->TheCapturedDecl->addAttr(
2823        AlwaysInlineAttr::CreateImplicit(
2824            Context, AlwaysInlineAttr::Keyword_forceinline));
2825    Sema::CapturedParamNameType ParamsTarget[] = {
2826        std::make_pair(StringRef(), QualType()) // __context with shared vars
2827    };
2828    // Start a captured region for 'target' with no implicit parameters.
2829    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2830                             ParamsTarget);
2831    Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2832        std::make_pair(".global_tid."KmpInt32PtrTy),
2833        std::make_pair(".bound_tid."KmpInt32PtrTy),
2834        std::make_pair(StringRef(), QualType()) // __context with shared vars
2835    };
2836    // Start a captured region for 'teams' or 'parallel'.  Both regions have
2837    // the same implicit parameters.
2838    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2839                             ParamsTeamsOrParallel);
2840    break;
2841  }
2842  case OMPD_target:
2843  case OMPD_target_simd: {
2844    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(321).withConst();
2845    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2846    QualType KmpInt32PtrTy =
2847        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2848    QualType Args[] = {VoidPtrTy};
2849    FunctionProtoType::ExtProtoInfo EPI;
2850    EPI.Variadic = true;
2851    QualType CopyFnType = Context.getFunctionType(Context.VoidTyArgsEPI);
2852    Sema::CapturedParamNameType Params[] = {
2853        std::make_pair(".global_tid."KmpInt32Ty),
2854        std::make_pair(".part_id."KmpInt32PtrTy),
2855        std::make_pair(".privates."VoidPtrTy),
2856        std::make_pair(
2857            ".copy_fn.",
2858            Context.getPointerType(CopyFnType).withConst().withRestrict()),
2859        std::make_pair(".task_t."Context.VoidPtrTy.withConst()),
2860        std::make_pair(StringRef(), QualType()) // __context with shared vars
2861    };
2862    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2863                             Params);
2864    // Mark this captured region as inlined, because we don't use outlined
2865    // function directly.
2866    getCurCapturedRegion()->TheCapturedDecl->addAttr(
2867        AlwaysInlineAttr::CreateImplicit(
2868            Context, AlwaysInlineAttr::Keyword_forceinline));
2869    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2870                             std::make_pair(StringRef(), QualType()));
2871    break;
2872  }
2873  case OMPD_simd:
2874  case OMPD_for:
2875  case OMPD_for_simd:
2876  case OMPD_sections:
2877  case OMPD_section:
2878  case OMPD_single:
2879  case OMPD_master:
2880  case OMPD_critical:
2881  case OMPD_taskgroup:
2882  case OMPD_distribute:
2883  case OMPD_distribute_simd:
2884  case OMPD_ordered:
2885  case OMPD_atomic:
2886  case OMPD_target_data: {
2887    Sema::CapturedParamNameType Params[] = {
2888        std::make_pair(StringRef(), QualType()) // __context with shared vars
2889    };
2890    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2891                             Params);
2892    break;
2893  }
2894  case OMPD_task: {
2895    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(321).withConst();
2896    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2897    QualType KmpInt32PtrTy =
2898        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2899    QualType Args[] = {VoidPtrTy};
2900    FunctionProtoType::ExtProtoInfo EPI;
2901    EPI.Variadic = true;
2902    QualType CopyFnType = Context.getFunctionType(Context.VoidTyArgsEPI);
2903    Sema::CapturedParamNameType Params[] = {
2904        std::make_pair(".global_tid."KmpInt32Ty),
2905        std::make_pair(".part_id."KmpInt32PtrTy),
2906        std::make_pair(".privates."VoidPtrTy),
2907        std::make_pair(
2908            ".copy_fn.",
2909            Context.getPointerType(CopyFnType).withConst().withRestrict()),
2910        std::make_pair(".task_t."Context.VoidPtrTy.withConst()),
2911        std::make_pair(StringRef(), QualType()) // __context with shared vars
2912    };
2913    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2914                             Params);
2915    // Mark this captured region as inlined, because we don't use outlined
2916    // function directly.
2917    getCurCapturedRegion()->TheCapturedDecl->addAttr(
2918        AlwaysInlineAttr::CreateImplicit(
2919            Context, AlwaysInlineAttr::Keyword_forceinline));
2920    break;
2921  }
2922  case OMPD_taskloop:
2923  case OMPD_taskloop_simd: {
2924    QualType KmpInt32Ty =
2925        Context.getIntTypeForBitwidth(/*DestWidth=*/32/*Signed=*/1)
2926            .withConst();
2927    QualType KmpUInt64Ty =
2928        Context.getIntTypeForBitwidth(/*DestWidth=*/64/*Signed=*/0)
2929            .withConst();
2930    QualType KmpInt64Ty =
2931        Context.getIntTypeForBitwidth(/*DestWidth=*/64/*Signed=*/1)
2932            .withConst();
2933    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2934    QualType KmpInt32PtrTy =
2935        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2936    QualType Args[] = {VoidPtrTy};
2937    FunctionProtoType::ExtProtoInfo EPI;
2938    EPI.Variadic = true;
2939    QualType CopyFnType = Context.getFunctionType(Context.VoidTyArgsEPI);
2940    Sema::CapturedParamNameType Params[] = {
2941        std::make_pair(".global_tid."KmpInt32Ty),
2942        std::make_pair(".part_id."KmpInt32PtrTy),
2943        std::make_pair(".privates."VoidPtrTy),
2944        std::make_pair(
2945            ".copy_fn.",
2946            Context.getPointerType(CopyFnType).withConst().withRestrict()),
2947        std::make_pair(".task_t."Context.VoidPtrTy.withConst()),
2948        std::make_pair(".lb."KmpUInt64Ty),
2949        std::make_pair(".ub."KmpUInt64Ty),
2950        std::make_pair(".st."KmpInt64Ty),
2951        std::make_pair(".liter."KmpInt32Ty),
2952        std::make_pair(".reductions."VoidPtrTy),
2953        std::make_pair(StringRef(), QualType()) // __context with shared vars
2954    };
2955    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2956                             Params);
2957    // Mark this captured region as inlined, because we don't use outlined
2958    // function directly.
2959    getCurCapturedRegion()->TheCapturedDecl->addAttr(
2960        AlwaysInlineAttr::CreateImplicit(
2961            Context, AlwaysInlineAttr::Keyword_forceinline));
2962    break;
2963  }
2964  case OMPD_distribute_parallel_for_simd:
2965  case OMPD_distribute_parallel_for: {
2966    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(321).withConst();
2967    QualType KmpInt32PtrTy =
2968        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2969    Sema::CapturedParamNameType Params[] = {
2970        std::make_pair(".global_tid."KmpInt32PtrTy),
2971        std::make_pair(".bound_tid."KmpInt32PtrTy),
2972        std::make_pair(".previous.lb."Context.getSizeType().withConst()),
2973        std::make_pair(".previous.ub."Context.getSizeType().withConst()),
2974        std::make_pair(StringRef(), QualType()) // __context with shared vars
2975    };
2976    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
2977                             Params);
2978    break;
2979  }
2980  case OMPD_target_teams_distribute_parallel_for:
2981  case OMPD_target_teams_distribute_parallel_for_simd: {
2982    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(321).withConst();
2983    QualType KmpInt32PtrTy =
2984        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2985    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2986
2987    QualType Args[] = {VoidPtrTy};
2988    FunctionProtoType::ExtProtoInfo EPI;
2989    EPI.Variadic = true;
2990    QualType CopyFnType = Context.getFunctionType(Context.VoidTyArgsEPI);
2991    Sema::CapturedParamNameType Params[] = {
2992        std::make_pair(".global_tid."KmpInt32Ty),
2993        std::make_pair(".part_id."KmpInt32PtrTy),
2994        std::make_pair(".privates."VoidPtrTy),
2995        std::make_pair(
2996            ".copy_fn.",
2997            Context.getPointerType(CopyFnType).withConst().withRestrict()),
2998        std::make_pair(".task_t."Context.VoidPtrTy.withConst()),
2999        std::make_pair(StringRef(), QualType()) // __context with shared vars
3000    };
3001    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
3002                             Params);
3003    // Mark this captured region as inlined, because we don't use outlined
3004    // function directly.
3005    getCurCapturedRegion()->TheCapturedDecl->addAttr(
3006        AlwaysInlineAttr::CreateImplicit(
3007            Context, AlwaysInlineAttr::Keyword_forceinline));
3008    Sema::CapturedParamNameType ParamsTarget[] = {
3009        std::make_pair(StringRef(), QualType()) // __context with shared vars
3010    };
3011    // Start a captured region for 'target' with no implicit parameters.
3012    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
3013                             ParamsTarget);
3014
3015    Sema::CapturedParamNameType ParamsTeams[] = {
3016        std::make_pair(".global_tid."KmpInt32PtrTy),
3017        std::make_pair(".bound_tid."KmpInt32PtrTy),
3018        std::make_pair(StringRef(), QualType()) // __context with shared vars
3019    };
3020    // Start a captured region for 'target' with no implicit parameters.
3021    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
3022                             ParamsTeams);
3023
3024    Sema::CapturedParamNameType ParamsParallel[] = {
3025        std::make_pair(".global_tid."KmpInt32PtrTy),
3026        std::make_pair(".bound_tid."KmpInt32PtrTy),
3027        std::make_pair(".previous.lb."Context.getSizeType().withConst()),
3028        std::make_pair(".previous.ub."Context.getSizeType().withConst()),
3029        std::make_pair(StringRef(), QualType()) // __context with shared vars
3030    };
3031    // Start a captured region for 'teams' or 'parallel'.  Both regions have
3032    // the same implicit parameters.
3033    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
3034                             ParamsParallel);
3035    break;
3036  }
3037
3038  case OMPD_teams_distribute_parallel_for:
3039  case OMPD_teams_distribute_parallel_for_simd: {
3040    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(321).withConst();
3041    QualType KmpInt32PtrTy =
3042        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3043
3044    Sema::CapturedParamNameType ParamsTeams[] = {
3045        std::make_pair(".global_tid."KmpInt32PtrTy),
3046        std::make_pair(".bound_tid."KmpInt32PtrTy),
3047        std::make_pair(StringRef(), QualType()) // __context with shared vars
3048    };
3049    // Start a captured region for 'target' with no implicit parameters.
3050    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
3051                             ParamsTeams);
3052
3053    Sema::CapturedParamNameType ParamsParallel[] = {
3054        std::make_pair(".global_tid."KmpInt32PtrTy),
3055        std::make_pair(".bound_tid."KmpInt32PtrTy),
3056        std::make_pair(".previous.lb."Context.getSizeType().withConst()),
3057        std::make_pair(".previous.ub."Context.getSizeType().withConst()),
3058        std::make_pair(StringRef(), QualType()) // __context with shared vars
3059    };
3060    // Start a captured region for 'teams' or 'parallel'.  Both regions have
3061    // the same implicit parameters.
3062    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
3063                             ParamsParallel);
3064    break;
3065  }
3066  case OMPD_target_update:
3067  case OMPD_target_enter_data:
3068  case OMPD_target_exit_data: {
3069    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(321).withConst();
3070    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3071    QualType KmpInt32PtrTy =
3072        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3073    QualType Args[] = {VoidPtrTy};
3074    FunctionProtoType::ExtProtoInfo EPI;
3075    EPI.Variadic = true;
3076    QualType CopyFnType = Context.getFunctionType(Context.VoidTyArgsEPI);
3077    Sema::CapturedParamNameType Params[] = {
3078        std::make_pair(".global_tid."KmpInt32Ty),
3079        std::make_pair(".part_id."KmpInt32PtrTy),
3080        std::make_pair(".privates."VoidPtrTy),
3081        std::make_pair(
3082            ".copy_fn.",
3083            Context.getPointerType(CopyFnType).withConst().withRestrict()),
3084        std::make_pair(".task_t."Context.VoidPtrTy.withConst()),
3085        std::make_pair(StringRef(), QualType()) // __context with shared vars
3086    };
3087    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScopeCR_OpenMP,
3088                             Params);
3089    // Mark this captured region as inlined, because we don't use outlined
3090    // function directly.
3091    getCurCapturedRegion()->TheCapturedDecl->addAttr(
3092        AlwaysInlineAttr::CreateImplicit(
3093            Context, AlwaysInlineAttr::Keyword_forceinline));
3094    break;
3095  }
3096  case OMPD_threadprivate:
3097  case OMPD_allocate:
3098  case OMPD_taskyield:
3099  case OMPD_barrier:
3100  case OMPD_taskwait:
3101  case OMPD_cancellation_point:
3102  case OMPD_cancel:
3103  case OMPD_flush:
3104  case OMPD_declare_reduction:
3105  case OMPD_declare_mapper:
3106  case OMPD_declare_simd:
3107  case OMPD_declare_target:
3108  case OMPD_end_declare_target:
3109  case OMPD_requires:
3110    llvm_unreachable("OpenMP Directive is not allowed");
3111  case OMPD_unknown:
3112    llvm_unreachable("Unknown OpenMP directive");
3113  }
3114}
3115
3116int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
3117  SmallVector<OpenMPDirectiveKind4CaptureRegions;
3118  getOpenMPCaptureRegions(CaptureRegions, DKind);
3119  return CaptureRegions.size();
3120}
3121
3122static OMPCapturedExprDecl *buildCaptureDecl(Sema &SIdentifierInfo *Id,
3123                                             Expr *CaptureExprbool WithInit,
3124                                             bool AsExpression) {
3125  assert(CaptureExpr);
3126  ASTContext &C = S.getASTContext();
3127  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
3128  QualType Ty = Init->getType();
3129  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
3130    if (S.getLangOpts().CPlusPlus) {
3131      Ty = C.getLValueReferenceType(Ty);
3132    } else {
3133      Ty = C.getPointerType(Ty);
3134      ExprResult Res =
3135          S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOfInit);
3136      if (!Res.isUsable())
3137        return nullptr;
3138      Init = Res.get();
3139    }
3140    WithInit = true;
3141  }
3142  auto *CED = OMPCapturedExprDecl::Create(CS.CurContextIdTy,
3143                                          CaptureExpr->getBeginLoc());
3144  if (!WithInit)
3145    CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
3146  S.CurContext->addHiddenDecl(CED);
3147  S.AddInitializerToDecl(CEDInit/*DirectInit=*/false);
3148  return CED;
3149}
3150
3151static DeclRefExpr *buildCapture(Sema &SValueDecl *DExpr *CaptureExpr,
3152                                 bool WithInit) {
3153  OMPCapturedExprDecl *CD;
3154  if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
3155    CD = cast<OMPCapturedExprDecl>(VD);
3156  else
3157    CD = buildCaptureDecl(SD->getIdentifier(), CaptureExprWithInit,
3158                          /*AsExpression=*/false);
3159  return buildDeclRefExpr(SCDCD->getType().getNonReferenceType(),
3160                          CaptureExpr->getExprLoc());
3161}
3162
3163static ExprResult buildCapture(Sema &SExpr *CaptureExprDeclRefExpr *&Ref) {
3164  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
3165  if (!Ref) {
3166    OMPCapturedExprDecl *CD = buildCaptureDecl(
3167        S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
3168        /*WithInit=*/true/*AsExpression=*/true);
3169    Ref = buildDeclRefExpr(SCDCD->getType().getNonReferenceType(),
3170                           CaptureExpr->getExprLoc());
3171  }
3172  ExprResult Res = Ref;
3173  if (!S.getLangOpts().CPlusPlus &&
3174      CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
3175      Ref->getType()->isPointerType()) {
3176    Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_DerefRef);
3177    if (!Res.isUsable())
3178      return ExprError();
3179  }
3180  return S.DefaultLvalueConversion(Res.get());
3181}
3182
3183namespace {
3184// OpenMP directives parsed in this section are represented as a
3185// CapturedStatement with an associated statement.  If a syntax error
3186// is detected during the parsing of the associated statement, the
3187// compiler must abort processing and close the CapturedStatement.
3188//
3189// Combined directives such as 'target parallel' have more than one
3190// nested CapturedStatements.  This RAII ensures that we unwind out
3191// of all the nested CapturedStatements when an error is found.
3192class CaptureRegionUnwinderRAII {
3193private:
3194  Sema &S;
3195  bool &ErrorFound;
3196  OpenMPDirectiveKind DKind = OMPD_unknown;
3197
3198public:
3199  CaptureRegionUnwinderRAII(Sema &Sbool &ErrorFound,
3200                            OpenMPDirectiveKind DKind)
3201      : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
3202  ~CaptureRegionUnwinderRAII() {
3203    if (ErrorFound) {
3204      int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
3205      while (--ThisCaptureLevel >= 0)
3206        S.ActOnCapturedRegionError();
3207    }
3208  }
3209};
3210// namespace
3211
3212StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
3213                                      ArrayRef<OMPClause *> Clauses) {
3214  bool ErrorFound = false;
3215  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
3216      *thisErrorFoundDSAStack->getCurrentDirective());
3217  if (!S.isUsable()) {
3218    ErrorFound = true;
3219    return StmtError();
3220  }
3221
3222  SmallVector<OpenMPDirectiveKind4CaptureRegions;
3223  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
3224  OMPOrderedClause *OC = nullptr;
3225  OMPScheduleClause *SC = nullptr;
3226  SmallVector<const OMPLinearClause *, 4LCs;
3227  SmallVector<const OMPClauseWithPreInit *, 4PICs;
3228  // This is required for proper codegen.
3229  for (OMPClause *Clause : Clauses) {
3230    if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
3231        Clause->getClauseKind() == OMPC_in_reduction) {
3232      // Capture taskgroup task_reduction descriptors inside the tasking regions
3233      // with the corresponding in_reduction items.
3234      auto *IRC = cast<OMPInReductionClause>(Clause);
3235      for (Expr *E : IRC->taskgroup_descriptors())
3236        if (E)
3237          MarkDeclarationsReferencedInExpr(E);
3238    }
3239    if (isOpenMPPrivate(Clause->getClauseKind()) ||
3240        Clause->getClauseKind() == OMPC_copyprivate ||
3241        (getLangOpts().OpenMPUseTLS &&
3242         getASTContext().getTargetInfo().isTLSSupported() &&
3243         Clause->getClauseKind() == OMPC_copyin)) {
3244      DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
3245      // Mark all variables in private list clauses as used in inner region.
3246      for (Stmt *VarRef : Clause->children()) {
3247        if (auto *E = cast_or_null<Expr>(VarRef)) {
3248          MarkDeclarationsReferencedInExpr(E);
3249        }
3250      }
3251      DSAStack->setForceVarCapturing(/*V=*/false);
3252    } else if (CaptureRegions.size() > 1 ||
3253               CaptureRegions.back() != OMPD_unknown) {
3254      if (auto *C = OMPClauseWithPreInit::get(Clause))
3255        PICs.push_back(C);
3256      if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
3257        if (Expr *E = C->getPostUpdateExpr())
3258          MarkDeclarationsReferencedInExpr(E);
3259      }
3260    }
3261    if (Clause->getClauseKind() == OMPC_schedule)
3262      SC = cast<OMPScheduleClause>(Clause);
3263    else if (Clause->getClauseKind() == OMPC_ordered)
3264      OC = cast<OMPOrderedClause>(Clause);
3265    else if (Clause->getClauseKind() == OMPC_linear)
3266      LCs.push_back(cast<OMPLinearClause>(Clause));
3267  }
3268  // OpenMP, 2.7.1 Loop Construct, Restrictions
3269  // The nonmonotonic modifier cannot be specified if an ordered clause is
3270  // specified.
3271  if (SC &&
3272      (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
3273       SC->getSecondScheduleModifier() ==
3274           OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
3275      OC) {
3276    Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
3277             ? SC->getFirstScheduleModifierLoc()
3278             : SC->getSecondScheduleModifierLoc(),
3279         diag::err_omp_schedule_nonmonotonic_ordered)
3280        << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3281    ErrorFound = true;
3282  }
3283  if (!LCs.empty() && OC && OC->getNumForLoops()) {
3284    for (const OMPLinearClause *C : LCs) {
3285      Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
3286          << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3287    }
3288    ErrorFound = true;
3289  }
3290  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
3291      isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
3292      OC->getNumForLoops()) {
3293    Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
3294        << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
3295    ErrorFound = true;
3296  }
3297  if (ErrorFound) {
3298    return StmtError();
3299  }
3300  StmtResult SR = S;
3301  for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
3302    // Mark all variables in private list clauses as used in inner region.
3303    // Required for proper codegen of combined directives.
3304    // TODO: add processing for other clauses.
3305    if (ThisCaptureRegion != OMPD_unknown) {
3306      for (const clang::OMPClauseWithPreInit *C : PICs) {
3307        OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
3308        // Find the particular capture region for the clause if the
3309        // directive is a combined one with multiple capture regions.
3310        // If the directive is not a combined one, the capture region
3311        // associated with the clause is OMPD_unknown and is generated
3312        // only once.
3313        if (CaptureRegion == ThisCaptureRegion ||
3314            CaptureRegion == OMPD_unknown) {
3315          if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
3316            for (Decl *D : DS->decls())
3317              MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
3318          }
3319        }
3320      }
3321    }
3322    SR = ActOnCapturedRegionEnd(SR.get());
3323  }
3324  return SR;
3325}
3326
3327static bool checkCancelRegion(Sema &SemaRefOpenMPDirectiveKind CurrentRegion,
3328                              OpenMPDirectiveKind CancelRegion,
3329                              SourceLocation StartLoc) {
3330  // CancelRegion is only needed for cancel and cancellation_point.
3331  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3332    return false;
3333
3334  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3335      CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3336    return false;
3337
3338  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3339      << getOpenMPDirectiveName(CancelRegion);
3340  return true;
3341}
3342
3343static bool checkNestingOfRegions(Sema &SemaRefconst DSAStackTy *Stack,
3344                                  OpenMPDirectiveKind CurrentRegion,
3345                                  const DeclarationNameInfo &CurrentName,
3346                                  OpenMPDirectiveKind CancelRegion,
3347                                  SourceLocation StartLoc) {
3348  if (Stack->getCurScope()) {
3349    OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
3350    OpenMPDirectiveKind OffendingRegion = ParentRegion;
3351    bool NestingProhibited = false;
3352    bool CloseNesting = true;
3353    bool OrphanSeen = false;
3354    enum {
3355      NoRecommend,
3356      ShouldBeInParallelRegion,
3357      ShouldBeInOrderedRegion,
3358      ShouldBeInTargetRegion,
3359      ShouldBeInTeamsRegion
3360    } Recommend = NoRecommend;
3361    if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
3362      // OpenMP [2.16, Nesting of Regions]
3363      // OpenMP constructs may not be nested inside a simd region.
3364      // OpenMP [2.8.1,simd Construct, Restrictions]
3365      // An ordered construct with the simd clause is the only OpenMP
3366      // construct that can appear in the simd region.
3367      // Allowing a SIMD construct nested in another SIMD construct is an
3368      // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
3369      // message.
3370      SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
3371                                 ? diag::err_omp_prohibited_region_simd
3372                                 : diag::warn_omp_nesting_simd);
3373      return CurrentRegion != OMPD_simd;
3374    }
3375    if (ParentRegion == OMPD_atomic) {
3376      // OpenMP [2.16, Nesting of Regions]
3377      // OpenMP constructs may not be nested inside an atomic region.
3378      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3379      return true;
3380    }
3381    if (CurrentRegion == OMPD_section) {
3382      // OpenMP [2.7.2, sections Construct, Restrictions]
3383      // Orphaned section directives are prohibited. That is, the section
3384      // directives must appear within the sections construct and must not be
3385      // encountered elsewhere in the sections region.
3386      if (ParentRegion != OMPD_sections &&
3387          ParentRegion != OMPD_parallel_sections) {
3388        SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3389            << (ParentRegion != OMPD_unknown)
3390            << getOpenMPDirectiveName(ParentRegion);
3391        return true;
3392      }
3393      return false;
3394    }
3395    // Allow some constructs (except teams and cancellation constructs) to be
3396    // orphaned (they could be used in functions, called from OpenMP regions
3397    // with the required preconditions).
3398    if (ParentRegion == OMPD_unknown &&
3399        !isOpenMPNestingTeamsDirective(CurrentRegion) &&
3400        CurrentRegion != OMPD_cancellation_point &&
3401        CurrentRegion != OMPD_cancel)
3402      return false;
3403    if (CurrentRegion == OMPD_cancellation_point ||
3404        CurrentRegion == OMPD_cancel) {
3405      // OpenMP [2.16, Nesting of Regions]
3406      // A cancellation point construct for which construct-type-clause is
3407      // taskgroup must be nested inside a task construct. A cancellation
3408      // point construct for which construct-type-clause is not taskgroup must
3409      // be closely nested inside an OpenMP construct that matches the type
3410      // specified in construct-type-clause.
3411      // A cancel construct for which construct-type-clause is taskgroup must be
3412      // nested inside a task construct. A cancel construct for which
3413      // construct-type-clause is not taskgroup must be closely nested inside an
3414      // OpenMP construct that matches the type specified in
3415      // construct-type-clause.
3416      NestingProhibited =
3417          !((CancelRegion == OMPD_parallel &&
3418             (ParentRegion == OMPD_parallel ||
3419              ParentRegion == OMPD_target_parallel)) ||
3420            (CancelRegion == OMPD_for &&
3421             (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
3422              ParentRegion == OMPD_target_parallel_for ||
3423              ParentRegion == OMPD_distribute_parallel_for ||
3424              ParentRegion == OMPD_teams_distribute_parallel_for ||
3425              ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
3426            (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3427            (CancelRegion == OMPD_sections &&
3428             (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3429              ParentRegion == OMPD_parallel_sections)));
3430      OrphanSeen = ParentRegion == OMPD_unknown;
3431    } else if (CurrentRegion == OMPD_master) {
3432      // OpenMP [2.16, Nesting of Regions]
3433      // A master region may not be closely nested inside a worksharing,
3434      // atomic, or explicit task region.
3435      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3436                          isOpenMPTaskingDirective(ParentRegion);
3437    } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
3438      // OpenMP [2.16, Nesting of Regions]
3439      // A critical region may not be nested (closely or otherwise) inside a
3440      // critical region with the same name. Note that this restriction is not
3441      // sufficient to prevent deadlock.
3442      SourceLocation PreviousCriticalLoc;
3443      bool DeadLock = Stack->hasDirective(
3444          [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
3445                                              const DeclarationNameInfo &DNI,
3446                                              SourceLocation Loc) {
3447            if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
3448              PreviousCriticalLoc = Loc;
3449              return true;
3450            }
3451            return false;
3452          },
3453          false /* skip top directive */);
3454      if (DeadLock) {
3455        SemaRef.Diag(StartLoc,
3456                     diag::err_omp_prohibited_region_critical_same_name)
3457            << CurrentName.getName();
3458        if (PreviousCriticalLoc.isValid())
3459          SemaRef.Diag(PreviousCriticalLoc,
3460                       diag::note_omp_previous_critical_region);
3461        return true;
3462      }
3463    } else if (CurrentRegion == OMPD_barrier) {
3464      // OpenMP [2.16, Nesting of Regions]
3465      // A barrier region may not be closely nested inside a worksharing,
3466      // explicit task, critical, ordered, atomic, or master region.
3467      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3468                          isOpenMPTaskingDirective(ParentRegion) ||
3469                          ParentRegion == OMPD_master ||
3470                          ParentRegion == OMPD_critical ||
3471                          ParentRegion == OMPD_ordered;
3472    } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
3473               !isOpenMPParallelDirective(CurrentRegion) &&
3474               !isOpenMPTeamsDirective(CurrentRegion)) {
3475      // OpenMP [2.16, Nesting of Regions]
3476      // A worksharing region may not be closely nested inside a worksharing,
3477      // explicit task, critical, ordered, atomic, or master region.
3478      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3479                          isOpenMPTaskingDirective(ParentRegion) ||
3480                          ParentRegion == OMPD_master ||
3481                          ParentRegion == OMPD_critical ||
3482                          ParentRegion == OMPD_ordered;
3483      Recommend = ShouldBeInParallelRegion;
3484    } else if (CurrentRegion == OMPD_ordered) {
3485      // OpenMP [2.16, Nesting of Regions]
3486      // An ordered region may not be closely nested inside a critical,
3487      // atomic, or explicit task region.
3488      // An ordered region must be closely nested inside a loop region (or
3489      // parallel loop region) with an ordered clause.
3490      // OpenMP [2.8.1,simd Construct, Restrictions]
3491      // An ordered construct with the simd clause is the only OpenMP construct
3492      // that can appear in the simd region.
3493      NestingProhibited = ParentRegion == OMPD_critical ||
3494                          isOpenMPTaskingDirective(ParentRegion) ||
3495                          !(isOpenMPSimdDirective(ParentRegion) ||
3496                            Stack->isParentOrderedRegion());
3497      Recommend = ShouldBeInOrderedRegion;
3498    } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
3499      // OpenMP [2.16, Nesting of Regions]
3500      // If specified, a teams construct must be contained within a target
3501      // construct.
3502      NestingProhibited = ParentRegion != OMPD_target;
3503      OrphanSeen = ParentRegion == OMPD_unknown;
3504      Recommend = ShouldBeInTargetRegion;
3505    }
3506    if (!NestingProhibited &&
3507        !isOpenMPTargetExecutionDirective(CurrentRegion) &&
3508        !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
3509        (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
3510      // OpenMP [2.16, Nesting of Regions]
3511      // distribute, parallel, parallel sections, parallel workshare, and the
3512      // parallel loop and parallel loop SIMD constructs are the only OpenMP
3513      // constructs that can be closely nested in the teams region.
3514      NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
3515                          !isOpenMPDistributeDirective(CurrentRegion);
3516      Recommend = ShouldBeInParallelRegion;
3517    }
3518    if (!NestingProhibited &&
3519        isOpenMPNestingDistributeDirective(CurrentRegion)) {
3520      // OpenMP 4.5 [2.17 Nesting of Regions]
3521      // The region associated with the distribute construct must be strictly
3522      // nested inside a teams region
3523      NestingProhibited =
3524          (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
3525      Recommend = ShouldBeInTeamsRegion;
3526    }
3527    if (!NestingProhibited &&
3528        (isOpenMPTargetExecutionDirective(CurrentRegion) ||
3529         isOpenMPTargetDataManagementDirective(CurrentRegion))) {
3530      // OpenMP 4.5 [2.17 Nesting of Regions]
3531      // If a target, target update, target data, target enter data, or
3532      // target exit data construct is encountered during execution of a
3533      // target region, the behavior is unspecified.
3534      NestingProhibited = Stack->hasDirective(
3535          [&OffendingRegion](OpenMPDirectiveKind Kconst DeclarationNameInfo &,
3536                             SourceLocation) {
3537            if (isOpenMPTargetExecutionDirective(K)) {
3538              OffendingRegion = K;
3539              return true;
3540            }
3541            return false;
3542          },
3543          false /* don't skip top directive */);
3544      CloseNesting = false;
3545    }
3546    if (NestingProhibited) {
3547      if (OrphanSeen) {
3548        SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
3549            << getOpenMPDirectiveName(CurrentRegion) << Recommend;
3550      } else {
3551        SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
3552            << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
3553            << Recommend << getOpenMPDirectiveName(CurrentRegion);
3554      }
3555      return true;
3556    }
3557  }
3558  return false;
3559}
3560
3561static bool checkIfClauses(Sema &SOpenMPDirectiveKind Kind,
3562                           ArrayRef<OMPClause *> Clauses,
3563                           ArrayRef<OpenMPDirectiveKindAllowedNameModifiers) {
3564  bool ErrorFound = false;
3565  unsigned NamedModifiersNumber = 0;
3566  SmallVector<const OMPIfClause *, OMPC_unknown + 1FoundNameModifiers(
3567      OMPD_unknown + 1);
3568  SmallVector<SourceLocation4NameModifierLoc;
3569  for (const OMPClause *C : Clauses) {
3570    if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
3571      // At most one if clause without a directive-name-modifier can appear on
3572      // the directive.
3573      OpenMPDirectiveKind CurNM = IC->getNameModifier();
3574      if (FoundNameModifiers[CurNM]) {
3575        S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
3576            << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
3577            << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
3578        ErrorFound = true;
3579      } else if (CurNM != OMPD_unknown) {
3580        NameModifierLoc.push_back(IC->getNameModifierLoc());
3581        ++NamedModifiersNumber;
3582      }
3583      FoundNameModifiers[CurNM] = IC;
3584      if (CurNM == OMPD_unknown)
3585        continue;
3586      // Check if the specified name modifier is allowed for the current
3587      // directive.
3588      // At most one if clause with the particular directive-name-modifier can
3589      // appear on the directive.
3590      bool MatchFound = false;
3591      for (auto NM : AllowedNameModifiers) {
3592        if (CurNM == NM) {
3593          MatchFound = true;
3594          break;
3595        }
3596      }
3597      if (!MatchFound) {
3598        S.Diag(IC->getNameModifierLoc(),
3599               diag::err_omp_wrong_if_directive_name_modifier)
3600            << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
3601        ErrorFound = true;
3602      }
3603    }
3604  }
3605  // If any if clause on the directive includes a directive-name-modifier then
3606  // all if clauses on the directive must include a directive-name-modifier.
3607  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
3608    if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3609      S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
3610             diag::err_omp_no_more_if_clause);
3611    } else {
3612      std::string Values;
3613      std::string Sep(", ");
3614      unsigned AllowedCnt = 0;
3615      unsigned TotalAllowedNum =
3616          AllowedNameModifiers.size() - NamedModifiersNumber;
3617      for (unsigned Cnt = 0End = AllowedNameModifiers.size(); Cnt < End;
3618           ++Cnt) {
3619        OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
3620        if (!FoundNameModifiers[NM]) {
3621          Values += "'";
3622          Values += getOpenMPDirectiveName(NM);
3623          Values += "'";
3624          if (AllowedCnt + 2 == TotalAllowedNum)
3625            Values += " or ";
3626          else if (AllowedCnt + 1 != TotalAllowedNum)
3627            Values += Sep;
3628          ++AllowedCnt;
3629        }
3630      }
3631      S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
3632             diag::err_omp_unnamed_if_clause)
3633          << (TotalAllowedNum > 1) << Values;
3634    }
3635    for (SourceLocation Loc : NameModifierLoc) {
3636      S.Diag(Loc, diag::note_omp_previous_named_if_clause);
3637    }
3638    ErrorFound = true;
3639  }
3640  return ErrorFound;
3641}
3642
3643static bool checkAllocateClauses(Sema &SDSAStackTy *Stack,
3644                                 ArrayRef<OMPClause *> Clauses) {
3645   (0) . __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3646, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!S.CurContext->isDependentContext() &&
3646 (0) . __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3646, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Expected non-dependent context.");
3647  bool IsCorrect = true;
3648  auto AllocateRange =
3649      llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
3650  for (OMPClause *C : AllocateRange) {
3651    auto *AC = cast<OMPAllocateClause>(C);
3652    OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3653        getAllocatorKind(S, Stack, AC->getAllocator());
3654    // OpenMP, 2.11.4 allocate Clause, Restrictions.
3655    // For task, taskloop or target directives, allocation requests to memory
3656    // allocators with the trait access set to thread result in unspecified
3657    // behavior.
3658    if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
3659        (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
3660         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
3661      S.Diag(AC->getAllocator()->getExprLoc(),
3662             diag::warn_omp_allocate_thread_on_task_target_directive)
3663          << getOpenMPDirectiveName(Stack->getCurrentDirective());
3664      continue;
3665    }
3666  }
3667  return !IsCorrect;
3668}
3669
3670StmtResult Sema::ActOnOpenMPExecutableDirective(
3671    OpenMPDirectiveKind Kindconst DeclarationNameInfo &DirName,
3672    OpenMPDirectiveKind CancelRegionArrayRef<OMPClause *> Clauses,
3673    Stmt *AStmtSourceLocation StartLocSourceLocation EndLoc) {
3674  StmtResult Res = StmtError();
3675  // First check CancelRegion which is then used in checkNestingOfRegions.
3676  if (checkCancelRegion(*thisKindCancelRegionStartLoc) ||
3677      checkNestingOfRegions(*thisDSAStackKindDirNameCancelRegion,
3678                            StartLoc))
3679    return StmtError();
3680
3681  llvm::SmallVector<OMPClause *, 8ClausesWithImplicit;
3682  VarsWithInheritedDSAType VarsWithInheritedDSA;
3683  bool ErrorFound = false;
3684  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3685  if (AStmt && !CurContext->isDependentContext()) {
3686     (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3686, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
3687
3688    // Check default data sharing attributes for referenced variables.
3689    DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
3690    int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
3691    Stmt *S = AStmt;
3692    while (--ThisCaptureLevel >= 0)
3693      S = cast<CapturedStmt>(S)->getCapturedStmt();
3694    DSAChecker.Visit(S);
3695    if (DSAChecker.isErrorFound())
3696      return StmtError();
3697    // Generate list of implicitly defined firstprivate variables.
3698    VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3699
3700    SmallVector<Expr *, 4ImplicitFirstprivates(
3701        DSAChecker.getImplicitFirstprivate().begin(),
3702        DSAChecker.getImplicitFirstprivate().end());
3703    SmallVector<Expr *, 4ImplicitMaps(DSAChecker.getImplicitMap().begin(),
3704                                        DSAChecker.getImplicitMap().end());
3705    // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
3706    for (OMPClause *C : Clauses) {
3707      if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
3708        for (Expr *E : IRC->taskgroup_descriptors())
3709          if (E)
3710            ImplicitFirstprivates.emplace_back(E);
3711      }
3712    }
3713    if (!ImplicitFirstprivates.empty()) {
3714      if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
3715              ImplicitFirstprivates, SourceLocation(), SourceLocation(),
3716              SourceLocation())) {
3717        ClausesWithImplicit.push_back(Implicit);
3718        ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3719                     ImplicitFirstprivates.size();
3720      } else {
3721        ErrorFound = true;
3722      }
3723    }
3724    if (!ImplicitMaps.empty()) {
3725      CXXScopeSpec MapperIdScopeSpec;
3726      DeclarationNameInfo MapperId;
3727      if (OMPClause *Implicit = ActOnOpenMPMapClause(
3728              llvm::None, llvm::None, MapperIdScopeSpec, MapperId,
3729              OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(),
3730              SourceLocation(), ImplicitMaps, OMPVarListLocTy())) {
3731        ClausesWithImplicit.emplace_back(Implicit);
3732        ErrorFound |=
3733            cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
3734      } else {
3735        ErrorFound = true;
3736      }
3737    }
3738  }
3739
3740  llvm::SmallVector<OpenMPDirectiveKind4AllowedNameModifiers;
3741  switch (Kind) {
3742  case OMPD_parallel:
3743    Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3744                                       EndLoc);
3745    AllowedNameModifiers.push_back(OMPD_parallel);
3746    break;
3747  case OMPD_simd:
3748    Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3749                                   VarsWithInheritedDSA);
3750    break;
3751  case OMPD_for:
3752    Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3753                                  VarsWithInheritedDSA);
3754    break;
3755  case OMPD_for_simd:
3756    Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3757                                      EndLoc, VarsWithInheritedDSA);
3758    break;
3759  case OMPD_sections:
3760    Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3761                                       EndLoc);
3762    break;
3763  case OMPD_section:
3764     (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3765, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ClausesWithImplicit.empty() &&
3765 (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3765, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No clauses are allowed for 'omp section' directive");
3766    Res = ActOnOpenMPSectionDirective(AStmtStartLocEndLoc);
3767    break;
3768  case OMPD_single:
3769    Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3770                                     EndLoc);
3771    break;
3772  case OMPD_master:
3773     (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3774, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ClausesWithImplicit.empty() &&
3774 (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3774, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No clauses are allowed for 'omp master' directive");
3775    Res = ActOnOpenMPMasterDirective(AStmtStartLocEndLoc);
3776    break;
3777  case OMPD_critical:
3778    Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3779                                       StartLoc, EndLoc);
3780    break;
3781  case OMPD_parallel_for:
3782    Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3783                                          EndLoc, VarsWithInheritedDSA);
3784    AllowedNameModifiers.push_back(OMPD_parallel);
3785    break;
3786  case OMPD_parallel_for_simd:
3787    Res = ActOnOpenMPParallelForSimdDirective(
3788        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3789    AllowedNameModifiers.push_back(OMPD_parallel);
3790    break;
3791  case OMPD_parallel_sections:
3792    Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3793                                               StartLoc, EndLoc);
3794    AllowedNameModifiers.push_back(OMPD_parallel);
3795    break;
3796  case OMPD_task:
3797    Res =
3798        ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3799    AllowedNameModifiers.push_back(OMPD_task);
3800    break;
3801  case OMPD_taskyield:
3802     (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3803, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ClausesWithImplicit.empty() &&
3803 (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3803, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No clauses are allowed for 'omp taskyield' directive");
3804     (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3805, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(AStmt == nullptr &&
3805 (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3805, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No associated statement allowed for 'omp taskyield' directive");
3806    Res = ActOnOpenMPTaskyieldDirective(StartLocEndLoc);
3807    break;
3808  case OMPD_barrier:
3809     (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3810, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ClausesWithImplicit.empty() &&
3810 (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3810, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No clauses are allowed for 'omp barrier' directive");
3811     (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3812, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(AStmt == nullptr &&
3812 (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3812, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No associated statement allowed for 'omp barrier' directive");
3813    Res = ActOnOpenMPBarrierDirective(StartLocEndLoc);
3814    break;
3815  case OMPD_taskwait:
3816     (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3817, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ClausesWithImplicit.empty() &&
3817 (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3817, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No clauses are allowed for 'omp taskwait' directive");
3818     (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3819, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(AStmt == nullptr &&
3819 (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3819, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No associated statement allowed for 'omp taskwait' directive");
3820    Res = ActOnOpenMPTaskwaitDirective(StartLocEndLoc);
3821    break;
3822  case OMPD_taskgroup:
3823    Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
3824                                        EndLoc);
3825    break;
3826  case OMPD_flush:
3827     (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3828, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(AStmt == nullptr &&
3828 (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3828, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No associated statement allowed for 'omp flush' directive");
3829    Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3830    break;
3831  case OMPD_ordered:
3832    Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3833                                      EndLoc);
3834    break;
3835  case OMPD_atomic:
3836    Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3837                                     EndLoc);
3838    break;
3839  case OMPD_teams:
3840    Res =
3841        ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3842    break;
3843  case OMPD_target:
3844    Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3845                                     EndLoc);
3846    AllowedNameModifiers.push_back(OMPD_target);
3847    break;
3848  case OMPD_target_parallel:
3849    Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3850                                             StartLoc, EndLoc);
3851    AllowedNameModifiers.push_back(OMPD_target);
3852    AllowedNameModifiers.push_back(OMPD_parallel);
3853    break;
3854  case OMPD_target_parallel_for:
3855    Res = ActOnOpenMPTargetParallelForDirective(
3856        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3857    AllowedNameModifiers.push_back(OMPD_target);
3858    AllowedNameModifiers.push_back(OMPD_parallel);
3859    break;
3860  case OMPD_cancellation_point:
3861     (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3862, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ClausesWithImplicit.empty() &&
3862 (0) . __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3862, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No clauses are allowed for 'omp cancellation point' directive");
3863     (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3864, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3864 (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3864, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">                               "cancellation point' directive");
3865    Res = ActOnOpenMPCancellationPointDirective(StartLocEndLocCancelRegion);
3866    break;
3867  case OMPD_cancel:
3868     (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3869, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(AStmt == nullptr &&
3869 (0) . __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 3869, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "No associated statement allowed for 'omp cancel' directive");
3870    Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3871                                     CancelRegion);
3872    AllowedNameModifiers.push_back(OMPD_cancel);
3873    break;
3874  case OMPD_target_data:
3875    Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3876                                         EndLoc);
3877    AllowedNameModifiers.push_back(OMPD_target_data);
3878    break;
3879  case OMPD_target_enter_data:
3880    Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3881                                              EndLoc, AStmt);
3882    AllowedNameModifiers.push_back(OMPD_target_enter_data);
3883    break;
3884  case OMPD_target_exit_data:
3885    Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3886                                             EndLoc, AStmt);
3887    AllowedNameModifiers.push_back(OMPD_target_exit_data);
3888    break;
3889  case OMPD_taskloop:
3890    Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3891                                       EndLoc, VarsWithInheritedDSA);
3892    AllowedNameModifiers.push_back(OMPD_taskloop);
3893    break;
3894  case OMPD_taskloop_simd:
3895    Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3896                                           EndLoc, VarsWithInheritedDSA);
3897    AllowedNameModifiers.push_back(OMPD_taskloop);
3898    break;
3899  case OMPD_distribute:
3900    Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3901                                         EndLoc, VarsWithInheritedDSA);
3902    break;
3903  case OMPD_target_update:
3904    Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3905                                           EndLoc, AStmt);
3906    AllowedNameModifiers.push_back(OMPD_target_update);
3907    break;
3908  case OMPD_distribute_parallel_for:
3909    Res = ActOnOpenMPDistributeParallelForDirective(
3910        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3911    AllowedNameModifiers.push_back(OMPD_parallel);
3912    break;
3913  case OMPD_distribute_parallel_for_simd:
3914    Res = ActOnOpenMPDistributeParallelForSimdDirective(
3915        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3916    AllowedNameModifiers.push_back(OMPD_parallel);
3917    break;
3918  case OMPD_distribute_simd:
3919    Res = ActOnOpenMPDistributeSimdDirective(
3920        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3921    break;
3922  case OMPD_target_parallel_for_simd:
3923    Res = ActOnOpenMPTargetParallelForSimdDirective(
3924        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3925    AllowedNameModifiers.push_back(OMPD_target);
3926    AllowedNameModifiers.push_back(OMPD_parallel);
3927    break;
3928  case OMPD_target_simd:
3929    Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3930                                         EndLoc, VarsWithInheritedDSA);
3931    AllowedNameModifiers.push_back(OMPD_target);
3932    break;
3933  case OMPD_teams_distribute:
3934    Res = ActOnOpenMPTeamsDistributeDirective(
3935        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3936    break;
3937  case OMPD_teams_distribute_simd:
3938    Res = ActOnOpenMPTeamsDistributeSimdDirective(
3939        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3940    break;
3941  case OMPD_teams_distribute_parallel_for_simd:
3942    Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3943        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3944    AllowedNameModifiers.push_back(OMPD_parallel);
3945    break;
3946  case OMPD_teams_distribute_parallel_for:
3947    Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3948        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3949    AllowedNameModifiers.push_back(OMPD_parallel);
3950    break;
3951  case OMPD_target_teams:
3952    Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3953                                          EndLoc);
3954    AllowedNameModifiers.push_back(OMPD_target);
3955    break;
3956  case OMPD_target_teams_distribute:
3957    Res = ActOnOpenMPTargetTeamsDistributeDirective(
3958        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3959    AllowedNameModifiers.push_back(OMPD_target);
3960    break;
3961  case OMPD_target_teams_distribute_parallel_for:
3962    Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3963        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3964    AllowedNameModifiers.push_back(OMPD_target);
3965    AllowedNameModifiers.push_back(OMPD_parallel);
3966    break;
3967  case OMPD_target_teams_distribute_parallel_for_simd:
3968    Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3969        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3970    AllowedNameModifiers.push_back(OMPD_target);
3971    AllowedNameModifiers.push_back(OMPD_parallel);
3972    break;
3973  case OMPD_target_teams_distribute_simd:
3974    Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3975        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3976    AllowedNameModifiers.push_back(OMPD_target);
3977    break;
3978  case OMPD_declare_target:
3979  case OMPD_end_declare_target:
3980  case OMPD_threadprivate:
3981  case OMPD_allocate:
3982  case OMPD_declare_reduction:
3983  case OMPD_declare_mapper:
3984  case OMPD_declare_simd:
3985  case OMPD_requires:
3986    llvm_unreachable("OpenMP Directive is not allowed");
3987  case OMPD_unknown:
3988    llvm_unreachable("Unknown OpenMP directive");
3989  }
3990
3991  ErrorFound = Res.isInvalid() || ErrorFound;
3992
3993  for (const auto &P : VarsWithInheritedDSA) {
3994    Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3995        << P.first << P.second->getSourceRange();
3996  }
3997  ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3998
3999  if (!AllowedNameModifiers.empty())
4000    ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
4001                 ErrorFound;
4002
4003  // Check allocate clauses.
4004  if (!CurContext->isDependentContext()) {
4005    ErrorFound = checkAllocateClauses(*thisDSAStack, ClausesWithImplicit) ||
4006                 ErrorFound;
4007  }
4008
4009  if (ErrorFound)
4010    return StmtError();
4011
4012  if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) {
4013    Res.getAs<OMPExecutableDirective>()
4014        ->getStructuredBlock()
4015        ->setIsOMPStructuredBlock(true);
4016  }
4017
4018  return Res;
4019}
4020
4021Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
4022    DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BSExpr *Simdlen,
4023    ArrayRef<Expr *> UniformsArrayRef<Expr *> Aligneds,
4024    ArrayRef<Expr *> AlignmentsArrayRef<Expr *> Linears,
4025    ArrayRef<unsignedLinModifiersArrayRef<Expr *> StepsSourceRange SR) {
4026  assert(Aligneds.size() == Alignments.size());
4027  assert(Linears.size() == LinModifiers.size());
4028  assert(Linears.size() == Steps.size());
4029  if (!DG || DG.get().isNull())
4030    return DeclGroupPtrTy();
4031
4032  if (!DG.get().isSingleDecl()) {
4033    Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
4034    return DG;
4035  }
4036  Decl *ADecl = DG.get().getSingleDecl();
4037  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
4038    ADecl = FTD->getTemplatedDecl();
4039
4040  auto *FD = dyn_cast<FunctionDecl>(ADecl);
4041  if (!FD) {
4042    Diag(ADecl->getLocation(), diag::err_omp_function_expected);
4043    return DeclGroupPtrTy();
4044  }
4045
4046  // OpenMP [2.8.2, declare simd construct, Description]
4047  // The parameter of the simdlen clause must be a constant positive integer
4048  // expression.
4049  ExprResult SL;
4050  if (Simdlen)
4051    SL = VerifyPositiveIntegerConstantInClause(SimdlenOMPC_simdlen);
4052  // OpenMP [2.8.2, declare simd construct, Description]
4053  // The special this pointer can be used as if was one of the arguments to the
4054  // function in any of the linear, aligned, or uniform clauses.
4055  // The uniform clause declares one or more arguments to have an invariant
4056  // value for all concurrent invocations of the function in the execution of a
4057  // single SIMD loop.
4058  llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
4059  const Expr *UniformedLinearThis = nullptr;
4060  for (const Expr *E : Uniforms) {
4061    E = E->IgnoreParenImpCasts();
4062    if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4063      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
4064        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4065            FD->getParamDecl(PVD->getFunctionScopeIndex())
4066                    ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
4067          UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
4068          continue;
4069        }
4070    if (isa<CXXThisExpr>(E)) {
4071      UniformedLinearThis = E;
4072      continue;
4073    }
4074    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4075        << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4076  }
4077  // OpenMP [2.8.2, declare simd construct, Description]
4078  // The aligned clause declares that the object to which each list item points
4079  // is aligned to the number of bytes expressed in the optional parameter of
4080  // the aligned clause.
4081  // The special this pointer can be used as if was one of the arguments to the
4082  // function in any of the linear, aligned, or uniform clauses.
4083  // The type of list items appearing in the aligned clause must be array,
4084  // pointer, reference to array, or reference to pointer.
4085  llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
4086  const Expr *AlignedThis = nullptr;
4087  for (const Expr *E : Aligneds) {
4088    E = E->IgnoreParenImpCasts();
4089    if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4090      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4091        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
4092        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4093            FD->getParamDecl(PVD->getFunctionScopeIndex())
4094                    ->getCanonicalDecl() == CanonPVD) {
4095          // OpenMP  [2.8.1, simd construct, Restrictions]
4096          // A list-item cannot appear in more than one aligned clause.
4097          if (AlignedArgs.count(CanonPVD) > 0) {
4098            Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
4099                << 1 << E->getSourceRange();
4100            Diag(AlignedArgs[CanonPVD]->getExprLoc(),
4101                 diag::note_omp_explicit_dsa)
4102                << getOpenMPClauseName(OMPC_aligned);
4103            continue;
4104          }
4105          AlignedArgs[CanonPVD] = E;
4106          QualType QTy = PVD->getType()
4107                             .getNonReferenceType()
4108                             .getUnqualifiedType()
4109                             .getCanonicalType();
4110          const Type *Ty = QTy.getTypePtrOrNull();
4111          if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
4112            Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
4113                << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
4114            Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
4115          }
4116          continue;
4117        }
4118      }
4119    if (isa<CXXThisExpr>(E)) {
4120      if (AlignedThis) {
4121        Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
4122            << 2 << E->getSourceRange();
4123        Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
4124            << getOpenMPClauseName(OMPC_aligned);
4125      }
4126      AlignedThis = E;
4127      continue;
4128    }
4129    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4130        << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4131  }
4132  // The optional parameter of the aligned clause, alignment, must be a constant
4133  // positive integer expression. If no optional parameter is specified,
4134  // implementation-defined default alignments for SIMD instructions on the
4135  // target platforms are assumed.
4136  SmallVector<const Expr *, 4NewAligns;
4137  for (Expr *E : Alignments) {
4138    ExprResult Align;
4139    if (E)
4140      Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
4141    NewAligns.push_back(Align.get());
4142  }
4143  // OpenMP [2.8.2, declare simd construct, Description]
4144  // The linear clause declares one or more list items to be private to a SIMD
4145  // lane and to have a linear relationship with respect to the iteration space
4146  // of a loop.
4147  // The special this pointer can be used as if was one of the arguments to the
4148  // function in any of the linear, aligned, or uniform clauses.
4149  // When a linear-step expression is specified in a linear clause it must be
4150  // either a constant integer expression or an integer-typed parameter that is
4151  // specified in a uniform clause on the directive.
4152  llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
4153  const bool IsUniformedThis = UniformedLinearThis != nullptr;
4154  auto MI = LinModifiers.begin();
4155  for (const Expr *E : Linears) {
4156    auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
4157    ++MI;
4158    E = E->IgnoreParenImpCasts();
4159    if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4160      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4161        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
4162        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4163            FD->getParamDecl(PVD->getFunctionScopeIndex())
4164                    ->getCanonicalDecl() == CanonPVD) {
4165          // OpenMP  [2.15.3.7, linear Clause, Restrictions]
4166          // A list-item cannot appear in more than one linear clause.
4167          if (LinearArgs.count(CanonPVD) > 0) {
4168            Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4169                << getOpenMPClauseName(OMPC_linear)
4170                << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
4171            Diag(LinearArgs[CanonPVD]->getExprLoc(),
4172                 diag::note_omp_explicit_dsa)
4173                << getOpenMPClauseName(OMPC_linear);
4174            continue;
4175          }
4176          // Each argument can appear in at most one uniform or linear clause.
4177          if (UniformedArgs.count(CanonPVD) > 0) {
4178            Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4179                << getOpenMPClauseName(OMPC_linear)
4180                << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
4181            Diag(UniformedArgs[CanonPVD]->getExprLoc(),
4182                 diag::note_omp_explicit_dsa)
4183                << getOpenMPClauseName(OMPC_uniform);
4184            continue;
4185          }
4186          LinearArgs[CanonPVD] = E;
4187          if (E->isValueDependent() || E->isTypeDependent() ||
4188              E->isInstantiationDependent() ||
4189              E->containsUnexpandedParameterPack())
4190            continue;
4191          (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
4192                                      PVD->getOriginalType());
4193          continue;
4194        }
4195      }
4196    if (isa<CXXThisExpr>(E)) {
4197      if (UniformedLinearThis) {
4198        Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4199            << getOpenMPClauseName(OMPC_linear)
4200            << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
4201            << E->getSourceRange();
4202        Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
4203            << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
4204                                                   : OMPC_linear);
4205        continue;
4206      }
4207      UniformedLinearThis = E;
4208      if (E->isValueDependent() || E->isTypeDependent() ||
4209          E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
4210        continue;
4211      (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
4212                                  E->getType());
4213      continue;
4214    }
4215    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4216        << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4217  }
4218  Expr *Step = nullptr;
4219  Expr *NewStep = nullptr;
4220  SmallVector<Expr *, 4NewSteps;
4221  for (Expr *E : Steps) {
4222    // Skip the same step expression, it was checked already.
4223    if (Step == E || !E) {
4224      NewSteps.push_back(E ? NewStep : nullptr);
4225      continue;
4226    }
4227    Step = E;
4228    if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
4229      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4230        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
4231        if (UniformedArgs.count(CanonPVD) == 0) {
4232          Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
4233              << Step->getSourceRange();
4234        } else if (E->isValueDependent() || E->isTypeDependent() ||
4235                   E->isInstantiationDependent() ||
4236                   E->containsUnexpandedParameterPack() ||
4237                   CanonPVD->getType()->hasIntegerRepresentation()) {
4238          NewSteps.push_back(Step);
4239        } else {
4240          Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
4241              << Step->getSourceRange();
4242        }
4243        continue;
4244      }
4245    NewStep = Step;
4246    if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
4247        !Step->isInstantiationDependent() &&
4248        !Step->containsUnexpandedParameterPack()) {
4249      NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
4250                    .get();
4251      if (NewStep)
4252        NewStep = VerifyIntegerConstantExpression(NewStep).get();
4253    }
4254    NewSteps.push_back(NewStep);
4255  }
4256  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
4257      Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
4258      Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
4259      const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
4260      const_cast<Expr **>(Linears.data()), Linears.size(),
4261      const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
4262      NewSteps.data(), NewSteps.size(), SR);
4263  ADecl->addAttr(NewAttr);
4264  return ConvertDeclToDeclGroup(ADecl);
4265}
4266
4267StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
4268                                              Stmt *AStmt,
4269                                              SourceLocation StartLoc,
4270                                              SourceLocation EndLoc) {
4271  if (!AStmt)
4272    return StmtError();
4273
4274  auto *CS = cast<CapturedStmt>(AStmt);
4275  // 1.2.2 OpenMP Language Terminology
4276  // Structured block - An executable statement with a single entry at the
4277  // top and a single exit at the bottom.
4278  // The point of exit cannot be a branch out of the structured block.
4279  // longjmp() and throw() must not violate the entry/exit criteria.
4280  CS->getCapturedDecl()->setNothrow();
4281
4282  setFunctionHasBranchProtectedScope();
4283
4284  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
4285                                      DSAStack->isCancelRegion());
4286}
4287
4288namespace {
4289/// Helper class for checking canonical form of the OpenMP loops and
4290/// extracting iteration space of each loop in the loop nest, that will be used
4291/// for IR generation.
4292class OpenMPIterationSpaceChecker {
4293  /// Reference to Sema.
4294  Sema &SemaRef;
4295  /// A location for diagnostics (when there is no some better location).
4296  SourceLocation DefaultLoc;
4297  /// A location for diagnostics (when increment is not compatible).
4298  SourceLocation ConditionLoc;
4299  /// A source location for referring to loop init later.
4300  SourceRange InitSrcRange;
4301  /// A source location for referring to condition later.
4302  SourceRange ConditionSrcRange;
4303  /// A source location for referring to increment later.
4304  SourceRange IncrementSrcRange;
4305  /// Loop variable.
4306  ValueDecl *LCDecl = nullptr;
4307  /// Reference to loop variable.
4308  Expr *LCRef = nullptr;
4309  /// Lower bound (initializer for the var).
4310  Expr *LB = nullptr;
4311  /// Upper bound.
4312  Expr *UB = nullptr;
4313  /// Loop step (increment).
4314  Expr *Step = nullptr;
4315  /// This flag is true when condition is one of:
4316  ///   Var <  UB
4317  ///   Var <= UB
4318  ///   UB  >  Var
4319  ///   UB  >= Var
4320  /// This will have no value when the condition is !=
4321  llvm::Optional<boolTestIsLessOp;
4322  /// This flag is true when condition is strict ( < or > ).
4323  bool TestIsStrictOp = false;
4324  /// This flag is true when step is subtracted on each iteration.
4325  bool SubtractStep = false;
4326
4327public:
4328  OpenMPIterationSpaceChecker(Sema &SemaRefSourceLocation DefaultLoc)
4329      : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
4330  /// Check init-expr for canonical loop form and save loop counter
4331  /// variable - #Var and its initialization value - #LB.
4332  bool checkAndSetInit(Stmt *Sbool EmitDiags = true);
4333  /// Check test-expr for canonical form, save upper-bound (#UB), flags
4334  /// for less/greater and for strict/non-strict comparison.
4335  bool checkAndSetCond(Expr *S);
4336  /// Check incr-expr for canonical loop form and return true if it
4337  /// does not conform, otherwise save loop step (#Step).
4338  bool checkAndSetInc(Expr *S);
4339  /// Return the loop counter variable.
4340  ValueDecl *getLoopDecl() const { return LCDecl; }
4341  /// Return the reference expression to loop counter variable.
4342  Expr *getLoopDeclRefExpr() const { return LCRef; }
4343  /// Source range of the loop init.
4344  SourceRange getInitSrcRange() const { return InitSrcRange; }
4345  /// Source range of the loop condition.
4346  SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
4347  /// Source range of the loop increment.
4348  SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
4349  /// True if the step should be subtracted.
4350  bool shouldSubtractStep() const { return SubtractStep; }
4351  /// True, if the compare operator is strict (<, > or !=).
4352  bool isStrictTestOp() const { return TestIsStrictOp; }
4353  /// Build the expression to calculate the number of iterations.
4354  Expr *buildNumIterations(
4355      Scope *Sconst bool LimitedType,
4356      llvm::MapVector<const Expr *, DeclRefExpr *> &Capturesconst;
4357  /// Build the precondition expression for the loops.
4358  Expr *
4359  buildPreCond(Scope *SExpr *Cond,
4360               llvm::MapVector<const Expr *, DeclRefExpr *> &Capturesconst;
4361  /// Build reference expression to the counter be used for codegen.
4362  DeclRefExpr *
4363  buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4364                  DSAStackTy &DSAconst;
4365  /// Build reference expression to the private counter be used for
4366  /// codegen.
4367  Expr *buildPrivateCounterVar() const;
4368  /// Build initialization of the counter be used for codegen.
4369  Expr *buildCounterInit() const;
4370  /// Build step of the counter be used for codegen.
4371  Expr *buildCounterStep() const;
4372  /// Build loop data with counter value for depend clauses in ordered
4373  /// directives.
4374  Expr *
4375  buildOrderedLoopData(Scope *SExpr *Counter,
4376                       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4377                       SourceLocation LocExpr *Inc = nullptr,
4378                       OverloadedOperatorKind OOK = OO_Amp);
4379  /// Return true if any expression is dependent.
4380  bool dependent() const;
4381
4382private:
4383  /// Check the right-hand side of an assignment in the increment
4384  /// expression.
4385  bool checkAndSetIncRHS(Expr *RHS);
4386  /// Helper to set loop counter variable and its initializer.
4387  bool setLCDeclAndLB(ValueDecl *NewLCDeclExpr *NewDeclRefExprExpr *NewLB);
4388  /// Helper to set upper bound.
4389  bool setUB(Expr *NewUBllvm::Optional<boolLessOpbool StrictOp,
4390             SourceRange SRSourceLocation SL);
4391  /// Helper to set loop increment.
4392  bool setStep(Expr *NewStepbool Subtract);
4393};
4394
4395bool OpenMPIterationSpaceChecker::dependent() const {
4396  if (!LCDecl) {
4397    assert(!LB && !UB && !Step);
4398    return false;
4399  }
4400  return LCDecl->getType()->isDependentType() ||
4401         (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
4402         (Step && Step->isValueDependent());
4403}
4404
4405bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
4406                                                 Expr *NewLCRefExpr,
4407                                                 Expr *NewLB) {
4408  // State consistency checking to ensure correct usage.
4409  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
4410         UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
4411  if (!NewLCDecl || !NewLB)
4412    return true;
4413  LCDecl = getCanonicalDecl(NewLCDecl);
4414  LCRef = NewLCRefExpr;
4415  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
4416    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
4417      if ((Ctor->isCopyOrMoveConstructor() ||
4418           Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4419          CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
4420        NewLB = CE->getArg(0)->IgnoreParenImpCasts();
4421  LB = NewLB;
4422  return false;
4423}
4424
4425bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
4426                                        llvm::Optional<boolLessOp,
4427                                        bool StrictOpSourceRange SR,
4428                                        SourceLocation SL) {
4429  // State consistency checking to ensure correct usage.
4430  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
4431         Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
4432  if (!NewUB)
4433    return true;
4434  UB = NewUB;
4435  if (LessOp)
4436    TestIsLessOp = LessOp;
4437  TestIsStrictOp = StrictOp;
4438  ConditionSrcRange = SR;
4439  ConditionLoc = SL;
4440  return false;
4441}
4442
4443bool OpenMPIterationSpaceChecker::setStep(Expr *NewStepbool Subtract) {
4444  // State consistency checking to ensure correct usage.
4445  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
4446  if (!NewStep)
4447    return true;
4448  if (!NewStep->isValueDependent()) {
4449    // Check that the step is integer expression.
4450    SourceLocation StepLoc = NewStep->getBeginLoc();
4451    ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
4452        StepLocgetExprAsWritten(NewStep));
4453    if (Val.isInvalid())
4454      return true;
4455    NewStep = Val.get();
4456
4457    // OpenMP [2.6, Canonical Loop Form, Restrictions]
4458    //  If test-expr is of form var relational-op b and relational-op is < or
4459    //  <= then incr-expr must cause var to increase on each iteration of the
4460    //  loop. If test-expr is of form var relational-op b and relational-op is
4461    //  > or >= then incr-expr must cause var to decrease on each iteration of
4462    //  the loop.
4463    //  If test-expr is of form b relational-op var and relational-op is < or
4464    //  <= then incr-expr must cause var to decrease on each iteration of the
4465    //  loop. If test-expr is of form b relational-op var and relational-op is
4466    //  > or >= then incr-expr must cause var to increase on each iteration of
4467    //  the loop.
4468    llvm::APSInt Result;
4469    bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
4470    bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
4471    bool IsConstNeg =
4472        IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
4473    bool IsConstPos =
4474        IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
4475    bool IsConstZero = IsConstant && !Result.getBoolValue();
4476
4477    // != with increment is treated as <; != with decrement is treated as >
4478    if (!TestIsLessOp.hasValue())
4479      TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
4480    if (UB && (IsConstZero ||
4481               (TestIsLessOp.getValue() ?
4482                  (IsConstNeg || (IsUnsigned && Subtract)) :
4483                  (IsConstPos || (IsUnsigned && !Subtract))))) {
4484      SemaRef.Diag(NewStep->getExprLoc(),
4485                   diag::err_omp_loop_incr_not_compatible)
4486          << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
4487      SemaRef.Diag(ConditionLoc,
4488                   diag::note_omp_loop_cond_requres_compatible_incr)
4489          << TestIsLessOp.getValue() << ConditionSrcRange;
4490      return true;
4491    }
4492    if (TestIsLessOp.getValue() == Subtract) {
4493      NewStep =
4494          SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_MinusNewStep)
4495              .get();
4496      Subtract = !Subtract;
4497    }
4498  }
4499
4500  Step = NewStep;
4501  SubtractStep = Subtract;
4502  return false;
4503}
4504
4505bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *Sbool EmitDiags) {
4506  // Check init-expr for canonical loop form and save loop counter
4507  // variable - #Var and its initialization value - #LB.
4508  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
4509  //   var = lb
4510  //   integer-type var = lb
4511  //   random-access-iterator-type var = lb
4512  //   pointer-type var = lb
4513  //
4514  if (!S) {
4515    if (EmitDiags) {
4516      SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
4517    }
4518    return true;
4519  }
4520  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4521    if (!ExprTemp->cleanupsHaveSideEffects())
4522      S = ExprTemp->getSubExpr();
4523
4524  InitSrcRange = S->getSourceRange();
4525  if (Expr *E = dyn_cast<Expr>(S))
4526    S = E->IgnoreParens();
4527  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4528    if (BO->getOpcode() == BO_Assign) {
4529      Expr *LHS = BO->getLHS()->IgnoreParens();
4530      if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4531        if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4532          if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4533            return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4534        return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
4535      }
4536      if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4537        if (ME->isArrow() &&
4538            isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4539          return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4540      }
4541    }
4542  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
4543    if (DS->isSingleDecl()) {
4544      if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
4545        if (Var->hasInit() && !Var->getType()->isReferenceType()) {
4546          // Accept non-canonical init form here but emit ext. warning.
4547          if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
4548            SemaRef.Diag(S->getBeginLoc(),
4549                         diag::ext_omp_loop_not_canonical_init)
4550                << S->getSourceRange();
4551          return setLCDeclAndLB(
4552              Var,
4553              buildDeclRefExpr(SemaRef, Var,
4554                               Var->getType().getNonReferenceType(),
4555                               DS->getBeginLoc()),
4556              Var->getInit());
4557        }
4558      }
4559    }
4560  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4561    if (CE->getOperator() == OO_Equal) {
4562      Expr *LHS = CE->getArg(0);
4563      if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4564        if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4565          if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4566            return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4567        return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
4568      }
4569      if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4570        if (ME->isArrow() &&
4571            isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4572          return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4573      }
4574    }
4575  }
4576
4577  if (dependent() || SemaRef.CurContext->isDependentContext())
4578    return false;
4579  if (EmitDiags) {
4580    SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
4581        << S->getSourceRange();
4582  }
4583  return true;
4584}
4585
4586/// Ignore parenthesizes, implicit casts, copy constructor and return the
4587/// variable (which may be the loop variable) if possible.
4588static const ValueDecl *getInitLCDecl(const Expr *E) {
4589  if (!E)
4590    return nullptr;
4591  E = getExprAsWritten(E);
4592  if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
4593    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
4594      if ((Ctor->isCopyOrMoveConstructor() ||
4595           Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4596          CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
4597        E = CE->getArg(0)->IgnoreParenImpCasts();
4598  if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
4599    if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
4600      return getCanonicalDecl(VD);
4601  }
4602  if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
4603    if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4604      return getCanonicalDecl(ME->getMemberDecl());
4605  return nullptr;
4606}
4607
4608bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
4609  // Check test-expr for canonical form, save upper-bound UB, flags for
4610  // less/greater and for strict/non-strict comparison.
4611  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4612  //   var relational-op b
4613  //   b relational-op var
4614  //
4615  if (!S) {
4616    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
4617    return true;
4618  }
4619  S = getExprAsWritten(S);
4620  SourceLocation CondLoc = S->getBeginLoc();
4621  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4622    if (BO->isRelationalOp()) {
4623      if (getInitLCDecl(BO->getLHS()) == LCDecl)
4624        return setUB(BO->getRHS(),
4625                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
4626                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4627                     BO->getSourceRange(), BO->getOperatorLoc());
4628      if (getInitLCDecl(BO->getRHS()) == LCDecl)
4629        return setUB(BO->getLHS(),
4630                     (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
4631                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4632                     BO->getSourceRange(), BO->getOperatorLoc());
4633    } else if (BO->getOpcode() == BO_NE)
4634        return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ?
4635                       BO->getRHS() : BO->getLHS(),
4636                     /*LessOp=*/llvm::None,
4637                     /*StrictOp=*/true,
4638                     BO->getSourceRange(), BO->getOperatorLoc());
4639  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4640    if (CE->getNumArgs() == 2) {
4641      auto Op = CE->getOperator();
4642      switch (Op) {
4643      case OO_Greater:
4644      case OO_GreaterEqual:
4645      case OO_Less:
4646      case OO_LessEqual:
4647        if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4648          return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4649                       Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4650                       CE->getOperatorLoc());
4651        if (getInitLCDecl(CE->getArg(1)) == LCDecl)
4652          return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4653                       Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4654                       CE->getOperatorLoc());
4655        break;
4656      case OO_ExclaimEqual:
4657        return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ?
4658                     CE->getArg(1) : CE->getArg(0),
4659                     /*LessOp=*/llvm::None,
4660                     /*StrictOp=*/true,
4661                     CE->getSourceRange(),
4662                     CE->getOperatorLoc());
4663        break;
4664      default:
4665        break;
4666      }
4667    }
4668  }
4669  if (dependent() || SemaRef.CurContext->isDependentContext())
4670    return false;
4671  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4672      << S->getSourceRange() << LCDecl;
4673  return true;
4674}
4675
4676bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
4677  // RHS of canonical loop form increment can be:
4678  //   var + incr
4679  //   incr + var
4680  //   var - incr
4681  //
4682  RHS = RHS->IgnoreParenImpCasts();
4683  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
4684    if (BO->isAdditiveOp()) {
4685      bool IsAdd = BO->getOpcode() == BO_Add;
4686      if (getInitLCDecl(BO->getLHS()) == LCDecl)
4687        return setStep(BO->getRHS(), !IsAdd);
4688      if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
4689        return setStep(BO->getLHS(), /*Subtract=*/false);
4690    }
4691  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4692    bool IsAdd = CE->getOperator() == OO_Plus;
4693    if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4694      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4695        return setStep(CE->getArg(1), !IsAdd);
4696      if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
4697        return setStep(CE->getArg(0), /*Subtract=*/false);
4698    }
4699  }
4700  if (dependent() || SemaRef.CurContext->isDependentContext())
4701    return false;
4702  SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
4703      << RHS->getSourceRange() << LCDecl;
4704  return true;
4705}
4706
4707bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
4708  // Check incr-expr for canonical loop form and return true if it
4709  // does not conform.
4710  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4711  //   ++var
4712  //   var++
4713  //   --var
4714  //   var--
4715  //   var += incr
4716  //   var -= incr
4717  //   var = var + incr
4718  //   var = incr + var
4719  //   var = var - incr
4720  //
4721  if (!S) {
4722    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4723    return true;
4724  }
4725  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4726    if (!ExprTemp->cleanupsHaveSideEffects())
4727      S = ExprTemp->getSubExpr();
4728
4729  IncrementSrcRange = S->getSourceRange();
4730  S = S->IgnoreParens();
4731  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
4732    if (UO->isIncrementDecrementOp() &&
4733        getInitLCDecl(UO->getSubExpr()) == LCDecl)
4734      return setStep(SemaRef
4735                         .ActOnIntegerConstant(UO->getBeginLoc(),
4736                                               (UO->isDecrementOp() ? -1 : 1))
4737                         .get(),
4738                     /*Subtract=*/false);
4739  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4740    switch (BO->getOpcode()) {
4741    case BO_AddAssign:
4742    case BO_SubAssign:
4743      if (getInitLCDecl(BO->getLHS()) == LCDecl)
4744        return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4745      break;
4746    case BO_Assign:
4747      if (getInitLCDecl(BO->getLHS()) == LCDecl)
4748        return checkAndSetIncRHS(BO->getRHS());
4749      break;
4750    default:
4751      break;
4752    }
4753  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4754    switch (CE->getOperator()) {
4755    case OO_PlusPlus:
4756    case OO_MinusMinus:
4757      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4758        return setStep(SemaRef
4759                           .ActOnIntegerConstant(
4760                               CE->getBeginLoc(),
4761                               ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
4762                           .get(),
4763                       /*Subtract=*/false);
4764      break;
4765    case OO_PlusEqual:
4766    case OO_MinusEqual:
4767      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4768        return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4769      break;
4770    case OO_Equal:
4771      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4772        return checkAndSetIncRHS(CE->getArg(1));
4773      break;
4774    default:
4775      break;
4776    }
4777  }
4778  if (dependent() || SemaRef.CurContext->isDependentContext())
4779    return false;
4780  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
4781      << S->getSourceRange() << LCDecl;
4782  return true;
4783}
4784
4785static ExprResult
4786tryBuildCapture(Sema &SemaRefExpr *Capture,
4787                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4788  if (SemaRef.CurContext->isDependentContext())
4789    return ExprResult(Capture);
4790  if (Capture->isEvaluatable(SemaRef.ContextExpr::SE_AllowSideEffects))
4791    return SemaRef.PerformImplicitConversion(
4792        Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
4793        /*AllowExplicit=*/true);
4794  auto I = Captures.find(Capture);
4795  if (I != Captures.end())
4796    return buildCapture(SemaRef, Capture, I->second);
4797  DeclRefExpr *Ref = nullptr;
4798  ExprResult Res = buildCapture(SemaRefCaptureRef);
4799  Captures[Capture] = Ref;
4800  return Res;
4801}
4802
4803/// Build the expression to calculate the number of iterations.
4804Expr *OpenMPIterationSpaceChecker::buildNumIterations(
4805    Scope *Sconst bool LimitedType,
4806    llvm::MapVector<const Expr *, DeclRefExpr *> &Capturesconst {
4807  ExprResult Diff;
4808  QualType VarType = LCDecl->getType().getNonReferenceType();
4809  if (VarType->isIntegerType() || VarType->isPointerType() ||
4810      SemaRef.getLangOpts().CPlusPlus) {
4811    // Upper - Lower
4812    Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
4813    Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
4814    Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4815    Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4816    if (!Upper || !Lower)
4817      return nullptr;
4818
4819    Diff = SemaRef.BuildBinOp(SDefaultLocBO_SubUpperLower);
4820
4821    if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4822      // BuildBinOp already emitted error, this one is to point user to upper
4823      // and lower bound, and to tell what is passed to 'operator-'.
4824      SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
4825          << Upper->getSourceRange() << Lower->getSourceRange();
4826      return nullptr;
4827    }
4828  }
4829
4830  if (!Diff.isUsable())
4831    return nullptr;
4832
4833  // Upper - Lower [- 1]
4834  if (TestIsStrictOp)
4835    Diff = SemaRef.BuildBinOp(
4836        SDefaultLocBO_SubDiff.get(),
4837        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4838  if (!Diff.isUsable())
4839    return nullptr;
4840
4841  // Upper - Lower [- 1] + Step
4842  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4843  if (!NewStep.isUsable())
4844    return nullptr;
4845  Diff = SemaRef.BuildBinOp(SDefaultLocBO_AddDiff.get(), NewStep.get());
4846  if (!Diff.isUsable())
4847    return nullptr;
4848
4849  // Parentheses (for dumping/debugging purposes only).
4850  Diff = SemaRef.ActOnParenExpr(DefaultLocDefaultLocDiff.get());
4851  if (!Diff.isUsable())
4852    return nullptr;
4853
4854  // (Upper - Lower [- 1] + Step) / Step
4855  Diff = SemaRef.BuildBinOp(SDefaultLocBO_DivDiff.get(), NewStep.get());
4856  if (!Diff.isUsable())
4857    return nullptr;
4858
4859  // OpenMP runtime requires 32-bit or 64-bit loop variables.
4860  QualType Type = Diff.get()->getType();
4861  ASTContext &C = SemaRef.Context;
4862  bool UseVarType = VarType->hasIntegerRepresentation() &&
4863                    C.getTypeSize(Type) > C.getTypeSize(VarType);
4864  if (!Type->isIntegerType() || UseVarType) {
4865    unsigned NewSize =
4866        UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
4867    bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
4868                               : Type->hasSignedIntegerRepresentation();
4869    Type = C.getIntTypeForBitwidth(NewSizeIsSigned);
4870    if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
4871      Diff = SemaRef.PerformImplicitConversion(
4872          Diff.get(), TypeSema::AA_Converting/*AllowExplicit=*/true);
4873      if (!Diff.isUsable())
4874        return nullptr;
4875    }
4876  }
4877  if (LimitedType) {
4878    unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
4879    if (NewSize != C.getTypeSize(Type)) {
4880      if (NewSize < C.getTypeSize(Type)) {
4881         (0) . __assert_fail ("NewSize == 64 && \"incorrect loop var size\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 4881, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(NewSize == 64 && "incorrect loop var size");
4882        SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4883            << InitSrcRange << ConditionSrcRange;
4884      }
4885      QualType NewType = C.getIntTypeForBitwidth(
4886          NewSizeType->hasSignedIntegerRepresentation() ||
4887                       C.getTypeSize(Type) < NewSize);
4888      if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4889        Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4890                                                 Sema::AA_Convertingtrue);
4891        if (!Diff.isUsable())
4892          return nullptr;
4893      }
4894    }
4895  }
4896
4897  return Diff.get();
4898}
4899
4900Expr *OpenMPIterationSpaceChecker::buildPreCond(
4901    Scope *SExpr *Cond,
4902    llvm::MapVector<const Expr *, DeclRefExpr *> &Capturesconst {
4903  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4904  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4905  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4906
4907  ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
4908  ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
4909  if (!NewLB.isUsable() || !NewUB.isUsable())
4910    return nullptr;
4911
4912  ExprResult CondExpr =
4913      SemaRef.BuildBinOp(S, DefaultLoc,
4914                         TestIsLessOp.getValue() ?
4915                           (TestIsStrictOp ? BO_LT : BO_LE) :
4916                           (TestIsStrictOp ? BO_GT : BO_GE),
4917                         NewLB.get(), NewUB.get());
4918  if (CondExpr.isUsable()) {
4919    if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4920                                                SemaRef.Context.BoolTy))
4921      CondExpr = SemaRef.PerformImplicitConversion(
4922          CondExpr.get(), SemaRef.Context.BoolTy/*Action=*/Sema::AA_Casting,
4923          /*AllowExplicit=*/true);
4924  }
4925  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4926  // Otherwise use original loop condition and evaluate it in runtime.
4927  return CondExpr.isUsable() ? CondExpr.get() : Cond;
4928}
4929
4930/// Build reference expression to the counter be used for codegen.
4931DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
4932    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4933    DSAStackTy &DSA) const {
4934  auto *VD = dyn_cast<VarDecl>(LCDecl);
4935  if (!VD) {
4936    VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
4937    DeclRefExpr *Ref = buildDeclRefExpr(
4938        SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4939    const DSAStackTy::DSAVarData Data =
4940        DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4941    // If the loop control decl is explicitly marked as private, do not mark it
4942    // as captured again.
4943    if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4944      Captures.insert(std::make_pair(LCRef, Ref));
4945    return Ref;
4946  }
4947  return cast<DeclRefExpr>(LCRef);
4948}
4949
4950Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
4951  if (LCDecl && !LCDecl->isInvalidDecl()) {
4952    QualType Type = LCDecl->getType().getNonReferenceType();
4953    VarDecl *PrivateVar = buildVarDecl(
4954        SemaRef, DefaultLoc, Type, LCDecl->getName(),
4955        LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
4956        isa<VarDecl>(LCDecl)
4957            ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
4958            : nullptr);
4959    if (PrivateVar->isInvalidDecl())
4960      return nullptr;
4961    return buildDeclRefExpr(SemaRefPrivateVarTypeDefaultLoc);
4962  }
4963  return nullptr;
4964}
4965
4966/// Build initialization of the counter to be used for codegen.
4967Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
4968
4969/// Build step of the counter be used for codegen.
4970Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
4971
4972Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
4973    Scope *SExpr *Counter,
4974    llvm::MapVector<const Expr *, DeclRefExpr *> &CapturesSourceLocation Loc,
4975    Expr *IncOverloadedOperatorKind OOK) {
4976  Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
4977  if (!Cnt)
4978    return nullptr;
4979  if (Inc) {
4980     (0) . __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 4981, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((OOK == OO_Plus || OOK == OO_Minus) &&
4981 (0) . __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 4981, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Expected only + or - operations for depend clauses.");
4982    BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
4983    Cnt = SemaRef.BuildBinOp(SLocBOKCntInc).get();
4984    if (!Cnt)
4985      return nullptr;
4986  }
4987  ExprResult Diff;
4988  QualType VarType = LCDecl->getType().getNonReferenceType();
4989  if (VarType->isIntegerType() || VarType->isPointerType() ||
4990      SemaRef.getLangOpts().CPlusPlus) {
4991    // Upper - Lower
4992    Expr *Upper = TestIsLessOp.getValue()
4993                      ? Cnt
4994                      : tryBuildCapture(SemaRef, UB, Captures).get();
4995    Expr *Lower = TestIsLessOp.getValue()
4996                      ? tryBuildCapture(SemaRef, LB, Captures).get()
4997                      : Cnt;
4998    if (!Upper || !Lower)
4999      return nullptr;
5000
5001    Diff = SemaRef.BuildBinOp(SDefaultLocBO_SubUpperLower);
5002
5003    if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
5004      // BuildBinOp already emitted error, this one is to point user to upper
5005      // and lower bound, and to tell what is passed to 'operator-'.
5006      SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
5007          << Upper->getSourceRange() << Lower->getSourceRange();
5008      return nullptr;
5009    }
5010  }
5011
5012  if (!Diff.isUsable())
5013    return nullptr;
5014
5015  // Parentheses (for dumping/debugging purposes only).
5016  Diff = SemaRef.ActOnParenExpr(DefaultLocDefaultLocDiff.get());
5017  if (!Diff.isUsable())
5018    return nullptr;
5019
5020  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
5021  if (!NewStep.isUsable())
5022    return nullptr;
5023  // (Upper - Lower) / Step
5024  Diff = SemaRef.BuildBinOp(SDefaultLocBO_DivDiff.get(), NewStep.get());
5025  if (!Diff.isUsable())
5026    return nullptr;
5027
5028  return Diff.get();
5029}
5030
5031/// Iteration space of a single for loop.
5032struct LoopIterationSpace final {
5033  /// True if the condition operator is the strict compare operator (<, > or
5034  /// !=).
5035  bool IsStrictCompare = false;
5036  /// Condition of the loop.
5037  Expr *PreCond = nullptr;
5038  /// This expression calculates the number of iterations in the loop.
5039  /// It is always possible to calculate it before starting the loop.
5040  Expr *NumIterations = nullptr;
5041  /// The loop counter variable.
5042  Expr *CounterVar = nullptr;
5043  /// Private loop counter variable.
5044  Expr *PrivateCounterVar = nullptr;
5045  /// This is initializer for the initial value of #CounterVar.
5046  Expr *CounterInit = nullptr;
5047  /// This is step for the #CounterVar used to generate its update:
5048  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
5049  Expr *CounterStep = nullptr;
5050  /// Should step be subtracted?
5051  bool Subtract = false;
5052  /// Source range of the loop init.
5053  SourceRange InitSrcRange;
5054  /// Source range of the loop condition.
5055  SourceRange CondSrcRange;
5056  /// Source range of the loop increment.
5057  SourceRange IncSrcRange;
5058};
5059
5060// namespace
5061
5062void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLocStmt *Init) {
5063   (0) . __assert_fail ("getLangOpts().OpenMP && \"OpenMP is not active.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 5063, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getLangOpts().OpenMP && "OpenMP is not active.");
5064   (0) . __assert_fail ("Init && \"Expected loop in canonical form.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 5064, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Init && "Expected loop in canonical form.");
5065  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
5066  if (AssociatedLoops > 0 &&
5067      isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
5068    DSAStack->loopStart();
5069    OpenMPIterationSpaceChecker ISC(*thisForLoc);
5070    if (!ISC.checkAndSetInit(Init/*EmitDiags=*/false)) {
5071      if (ValueDecl *D = ISC.getLoopDecl()) {
5072        auto *VD = dyn_cast<VarDecl>(D);
5073        if (!VD) {
5074          if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
5075            VD = Private;
5076          } else {
5077            DeclRefExpr *Ref = buildCapture(*thisDISC.getLoopDeclRefExpr(),
5078                                            /*WithInit=*/false);
5079            VD = cast<VarDecl>(Ref->getDecl());
5080          }
5081        }
5082        DSAStack->addLoopControlVariable(D, VD);
5083        const Decl *LD = DSAStack->getPossiblyLoopCunter();
5084        if (LD != D->getCanonicalDecl()) {
5085          DSAStack->resetPossibleLoopCounter();
5086          if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
5087            MarkDeclarationsReferencedInExpr(
5088                buildDeclRefExpr(*thisconst_cast<VarDecl *>(Var),
5089                                 Var->getType().getNonLValueExprType(Context),
5090                                 ForLoc, /*RefersToCapture=*/true));
5091        }
5092      }
5093    }
5094    DSAStack->setAssociatedLoops(AssociatedLoops - 1);
5095  }
5096}
5097
5098/// Called on a for stmt to check and extract its iteration space
5099/// for further processing (such as collapsing).
5100static bool checkOpenMPIterationSpace(
5101    OpenMPDirectiveKind DKindStmt *SSema &SemaRefDSAStackTy &DSA,
5102    unsigned CurrentNestedLoopCountunsigned NestedLoopCount,
5103    unsigned TotalNestedLoopCountExpr *CollapseLoopCountExpr,
5104    Expr *OrderedLoopCountExpr,
5105    Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
5106    LoopIterationSpace &ResultIterSpace,
5107    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5108  // OpenMP [2.6, Canonical Loop Form]
5109  //   for (init-expr; test-expr; incr-expr) structured-block
5110  auto *For = dyn_cast_or_null<ForStmt>(S);
5111  if (!For) {
5112    SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
5113        << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
5114        << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
5115        << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
5116    if (TotalNestedLoopCount > 1) {
5117      if (CollapseLoopCountExpr && OrderedLoopCountExpr)
5118        SemaRef.Diag(DSA.getConstructLoc(),
5119                     diag::note_omp_collapse_ordered_expr)
5120            << 2 << CollapseLoopCountExpr->getSourceRange()
5121            << OrderedLoopCountExpr->getSourceRange();
5122      else if (CollapseLoopCountExpr)
5123        SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
5124                     diag::note_omp_collapse_ordered_expr)
5125            << 0 << CollapseLoopCountExpr->getSourceRange();
5126      else
5127        SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
5128                     diag::note_omp_collapse_ordered_expr)
5129            << 1 << OrderedLoopCountExpr->getSourceRange();
5130    }
5131    return true;
5132  }
5133  getBody()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 5133, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(For->getBody());
5134
5135  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
5136
5137  // Check init.
5138  Stmt *Init = For->getInit();
5139  if (ISC.checkAndSetInit(Init))
5140    return true;
5141
5142  bool HasErrors = false;
5143
5144  // Check loop variable's type.
5145  if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
5146    Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
5147
5148    // OpenMP [2.6, Canonical Loop Form]
5149    // Var is one of the following:
5150    //   A variable of signed or unsigned integer type.
5151    //   For C++, a variable of a random access iterator type.
5152    //   For C, a variable of a pointer type.
5153    QualType VarType = LCDecl->getType().getNonReferenceType();
5154    if (!VarType->isDependentType() && !VarType->isIntegerType() &&
5155        !VarType->isPointerType() &&
5156        !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
5157      SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
5158          << SemaRef.getLangOpts().CPlusPlus;
5159      HasErrors = true;
5160    }
5161
5162    // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
5163    // a Construct
5164    // The loop iteration variable(s) in the associated for-loop(s) of a for or
5165    // parallel for construct is (are) private.
5166    // The loop iteration variable in the associated for-loop of a simd
5167    // construct with just one associated for-loop is linear with a
5168    // constant-linear-step that is the increment of the associated for-loop.
5169    // Exclude loop var from the list of variables with implicitly defined data
5170    // sharing attributes.
5171    VarsWithImplicitDSA.erase(LCDecl);
5172
5173    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
5174    // in a Construct, C/C++].
5175    // The loop iteration variable in the associated for-loop of a simd
5176    // construct with just one associated for-loop may be listed in a linear
5177    // clause with a constant-linear-step that is the increment of the
5178    // associated for-loop.
5179    // The loop iteration variable(s) in the associated for-loop(s) of a for or
5180    // parallel for construct may be listed in a private or lastprivate clause.
5181    DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDeclfalse);
5182    // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
5183    // declared in the loop and it is predetermined as a private.
5184    OpenMPClauseKind PredeterminedCKind =
5185        isOpenMPSimdDirective(DKind)
5186            ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
5187            : OMPC_private;
5188    if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
5189          DVar.CKind != PredeterminedCKind) ||
5190         ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
5191           isOpenMPDistributeDirective(DKind)) &&
5192          !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
5193          DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
5194        (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
5195      SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
5196          << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
5197          << getOpenMPClauseName(PredeterminedCKind);
5198      if (DVar.RefExpr == nullptr)
5199        DVar.CKind = PredeterminedCKind;
5200      reportOriginalDsa(SemaRef, &DSALCDeclDVar/*IsLoopIterVar=*/true);
5201      HasErrors = true;
5202    } else if (LoopDeclRefExpr != nullptr) {
5203      // Make the loop iteration variable private (for worksharing constructs),
5204      // linear (for simd directives with the only one associated loop) or
5205      // lastprivate (for simd directives with several collapsed or ordered
5206      // loops).
5207      if (DVar.CKind == OMPC_unknown)
5208        DSA.addDSA(LCDeclLoopDeclRefExprPredeterminedCKind);
5209    }
5210
5211     (0) . __assert_fail ("isOpenMPLoopDirective(DKind) && \"DSA for non-loop vars\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 5211, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
5212
5213    // Check test-expr.
5214    HasErrors |= ISC.checkAndSetCond(For->getCond());
5215
5216    // Check incr-expr.
5217    HasErrors |= ISC.checkAndSetInc(For->getInc());
5218  }
5219
5220  if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
5221    return HasErrors;
5222
5223  // Build the loop's iteration space representation.
5224  ResultIterSpace.PreCond =
5225      ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
5226  ResultIterSpace.NumIterations = ISC.buildNumIterations(
5227      DSA.getCurScope(),
5228      (isOpenMPWorksharingDirective(DKind) ||
5229       isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
5230      Captures);
5231  ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
5232  ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
5233  ResultIterSpace.CounterInit = ISC.buildCounterInit();
5234  ResultIterSpace.CounterStep = ISC.buildCounterStep();
5235  ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
5236  ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
5237  ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
5238  ResultIterSpace.Subtract = ISC.shouldSubtractStep();
5239  ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp();
5240
5241  HasErrors |= (ResultIterSpace.PreCond == nullptr ||
5242                ResultIterSpace.NumIterations == nullptr ||
5243                ResultIterSpace.CounterVar == nullptr ||
5244                ResultIterSpace.PrivateCounterVar == nullptr ||
5245                ResultIterSpace.CounterInit == nullptr ||
5246                ResultIterSpace.CounterStep == nullptr);
5247  if (!HasErrors && DSA.isOrderedRegion()) {
5248    if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
5249      if (CurrentNestedLoopCount <
5250          DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
5251        DSA.getOrderedRegionParam().second->setLoopNumIterations(
5252            CurrentNestedLoopCountResultIterSpace.NumIterations);
5253        DSA.getOrderedRegionParam().second->setLoopCounter(
5254            CurrentNestedLoopCountResultIterSpace.CounterVar);
5255      }
5256    }
5257    for (auto &Pair : DSA.getDoacrossDependClauses()) {
5258      if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
5259        // Erroneous case - clause has some problems.
5260        continue;
5261      }
5262      if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
5263          Pair.second.size() <= CurrentNestedLoopCount) {
5264        // Erroneous case - clause has some problems.
5265        Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
5266        continue;
5267      }
5268      Expr *CntValue;
5269      if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
5270        CntValue = ISC.buildOrderedLoopData(
5271            DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
5272            Pair.first->getDependencyLoc());
5273      else
5274        CntValue = ISC.buildOrderedLoopData(
5275            DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
5276            Pair.first->getDependencyLoc(),
5277            Pair.second[CurrentNestedLoopCount].first,
5278            Pair.second[CurrentNestedLoopCount].second);
5279      Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
5280    }
5281  }
5282
5283  return HasErrors;
5284}
5285
5286/// Build 'VarRef = Start.
5287static ExprResult
5288buildCounterInit(Sema &SemaRefScope *SSourceLocation LocExprResult VarRef,
5289                 ExprResult Start,
5290                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5291  // Build 'VarRef = Start.
5292  ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
5293  if (!NewStart.isUsable())
5294    return ExprError();
5295  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
5296                                   VarRef.get()->getType())) {
5297    NewStart = SemaRef.PerformImplicitConversion(
5298        NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
5299        /*AllowExplicit=*/true);
5300    if (!NewStart.isUsable())
5301      return ExprError();
5302  }
5303
5304  ExprResult Init =
5305      SemaRef.BuildBinOp(SLocBO_AssignVarRef.get(), NewStart.get());
5306  return Init;
5307}
5308
5309/// Build 'VarRef = Start + Iter * Step'.
5310static ExprResult buildCounterUpdate(
5311    Sema &SemaRefScope *SSourceLocation LocExprResult VarRef,
5312    ExprResult StartExprResult IterExprResult Stepbool Subtract,
5313    llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
5314  // Add parentheses (for debugging purposes only).
5315  Iter = SemaRef.ActOnParenExpr(LocLocIter.get());
5316  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
5317      !Step.isUsable())
5318    return ExprError();
5319
5320  ExprResult NewStep = Step;
5321  if (Captures)
5322    NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
5323  if (NewStep.isInvalid())
5324    return ExprError();
5325  ExprResult Update =
5326      SemaRef.BuildBinOp(SLocBO_MulIter.get(), NewStep.get());
5327  if (!Update.isUsable())
5328    return ExprError();
5329
5330  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
5331  // 'VarRef = Start (+|-) Iter * Step'.
5332  ExprResult NewStart = Start;
5333  if (Captures)
5334    NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
5335  if (NewStart.isInvalid())
5336    return ExprError();
5337
5338  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
5339  ExprResult SavedUpdate = Update;
5340  ExprResult UpdateVal;
5341  if (VarRef.get()->getType()->isOverloadableType() ||
5342      NewStart.get()->getType()->isOverloadableType() ||
5343      Update.get()->getType()->isOverloadableType()) {
5344    bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
5345    SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
5346    Update =
5347        SemaRef.BuildBinOp(SLocBO_AssignVarRef.get(), NewStart.get());
5348    if (Update.isUsable()) {
5349      UpdateVal =
5350          SemaRef.BuildBinOp(SLocSubtract ? BO_SubAssign : BO_AddAssign,
5351                             VarRef.get(), SavedUpdate.get());
5352      if (UpdateVal.isUsable()) {
5353        Update = SemaRef.CreateBuiltinBinOp(LocBO_CommaUpdate.get(),
5354                                            UpdateVal.get());
5355      }
5356    }
5357    SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
5358  }
5359
5360  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
5361  if (!Update.isUsable() || !UpdateVal.isUsable()) {
5362    Update = SemaRef.BuildBinOp(SLocSubtract ? BO_Sub : BO_Add,
5363                                NewStart.get(), SavedUpdate.get());
5364    if (!Update.isUsable())
5365      return ExprError();
5366
5367    if (!SemaRef.Context.hasSameType(Update.get()->getType(),
5368                                     VarRef.get()->getType())) {
5369      Update = SemaRef.PerformImplicitConversion(
5370          Update.get(), VarRef.get()->getType(), Sema::AA_Convertingtrue);
5371      if (!Update.isUsable())
5372        return ExprError();
5373    }
5374
5375    Update = SemaRef.BuildBinOp(SLocBO_AssignVarRef.get(), Update.get());
5376  }
5377  return Update;
5378}
5379
5380/// Convert integer expression \a E to make it have at least \a Bits
5381/// bits.
5382static ExprResult widenIterationCount(unsigned BitsExpr *ESema &SemaRef) {
5383  if (E == nullptr)
5384    return ExprError();
5385  ASTContext &C = SemaRef.Context;
5386  QualType OldType = E->getType();
5387  unsigned HasBits = C.getTypeSize(OldType);
5388  if (HasBits >= Bits)
5389    return ExprResult(E);
5390  // OK to convert to signed, because new type has more bits than old.
5391  QualType NewType = C.getIntTypeForBitwidth(Bits/* Signed */ true);
5392  return SemaRef.PerformImplicitConversion(ENewTypeSema::AA_Converting,
5393                                           true);
5394}
5395
5396/// Check if the given expression \a E is a constant integer that fits
5397/// into \a Bits bits.
5398static bool fitsInto(unsigned Bitsbool Signedconst Expr *ESema &SemaRef) {
5399  if (E == nullptr)
5400    return false;
5401  llvm::APSInt Result;
5402  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
5403    return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
5404  return false;
5405}
5406
5407/// Build preinits statement for the given declarations.
5408static Stmt *buildPreInits(ASTContext &Context,
5409                           MutableArrayRef<Decl *> PreInits) {
5410  if (!PreInits.empty()) {
5411    return new (Context) DeclStmt(
5412        DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
5413        SourceLocation(), SourceLocation());
5414  }
5415  return nullptr;
5416}
5417
5418/// Build preinits statement for the given declarations.
5419static Stmt *
5420buildPreInits(ASTContext &Context,
5421              const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5422  if (!Captures.empty()) {
5423    SmallVector<Decl *, 16PreInits;
5424    for (const auto &Pair : Captures)
5425      PreInits.push_back(Pair.second->getDecl());
5426    return buildPreInits(Context, PreInits);
5427  }
5428  return nullptr;
5429}
5430
5431/// Build postupdate expression for the given list of postupdates expressions.
5432static Expr *buildPostUpdate(Sema &SArrayRef<Expr *> PostUpdates) {
5433  Expr *PostUpdate = nullptr;
5434  if (!PostUpdates.empty()) {
5435    for (Expr *E : PostUpdates) {
5436      Expr *ConvE = S.BuildCStyleCastExpr(
5437                         E->getExprLoc(),
5438                         S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
5439                         E->getExprLoc(), E)
5440                        .get();
5441      PostUpdate = PostUpdate
5442                       ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
5443                                              PostUpdate, ConvE)
5444                             .get()
5445                       : ConvE;
5446    }
5447  }
5448  return PostUpdate;
5449}
5450
5451/// Called on a for stmt to check itself and nested loops (if any).
5452/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
5453/// number of collapsed loops otherwise.
5454static unsigned
5455checkOpenMPLoop(OpenMPDirectiveKind DKindExpr *CollapseLoopCountExpr,
5456                Expr *OrderedLoopCountExprStmt *AStmtSema &SemaRef,
5457                DSAStackTy &DSA,
5458                Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
5459                OMPLoopDirective::HelperExprs &Built) {
5460  unsigned NestedLoopCount = 1;
5461  if (CollapseLoopCountExpr) {
5462    // Found 'collapse' clause - calculate collapse number.
5463    Expr::EvalResult Result;
5464    if (CollapseLoopCountExpr->EvaluateAsInt(ResultSemaRef.getASTContext()))
5465      NestedLoopCount = Result.Val.getInt().getLimitedValue();
5466  }
5467  unsigned OrderedLoopCount = 1;
5468  if (OrderedLoopCountExpr) {
5469    // Found 'ordered' clause - calculate collapse number.
5470    Expr::EvalResult EVResult;
5471    if (OrderedLoopCountExpr->EvaluateAsInt(EVResultSemaRef.getASTContext())) {
5472      llvm::APSInt Result = EVResult.Val.getInt();
5473      if (Result.getLimitedValue() < NestedLoopCount) {
5474        SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
5475                     diag::err_omp_wrong_ordered_loop_count)
5476            << OrderedLoopCountExpr->getSourceRange();
5477        SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
5478                     diag::note_collapse_loop_count)
5479            << CollapseLoopCountExpr->getSourceRange();
5480      }
5481      OrderedLoopCount = Result.getLimitedValue();
5482    }
5483  }
5484  // This is helper routine for loop directives (e.g., 'for', 'simd',
5485  // 'for simd', etc.).
5486  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
5487  SmallVector<LoopIterationSpace4IterSpaces(
5488      std::max(OrderedLoopCount, NestedLoopCount));
5489  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
5490  for (unsigned Cnt = 0Cnt < NestedLoopCount; ++Cnt) {
5491    if (checkOpenMPIterationSpace(
5492            DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5493            std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5494            OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5495            Captures))
5496      return 0;
5497    // Move on to the next nested for loop, or to the loop body.
5498    // OpenMP [2.8.1, simd construct, Restrictions]
5499    // All loops associated with the construct must be perfectly nested; that
5500    // is, there must be no intervening code nor any OpenMP directive between
5501    // any two loops.
5502    CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
5503  }
5504  for (unsigned Cnt = NestedLoopCountCnt < OrderedLoopCount; ++Cnt) {
5505    if (checkOpenMPIterationSpace(
5506            DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5507            std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5508            OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5509            Captures))
5510      return 0;
5511    if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
5512      // Handle initialization of captured loop iterator variables.
5513      auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
5514      if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
5515        Captures[DRE] = DRE;
5516      }
5517    }
5518    // Move on to the next nested for loop, or to the loop body.
5519    // OpenMP [2.8.1, simd construct, Restrictions]
5520    // All loops associated with the construct must be perfectly nested; that
5521    // is, there must be no intervening code nor any OpenMP directive between
5522    // any two loops.
5523    CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
5524  }
5525
5526  Built.clear(/* size */ NestedLoopCount);
5527
5528  if (SemaRef.CurContext->isDependentContext())
5529    return NestedLoopCount;
5530
5531  // An example of what is generated for the following code:
5532  //
5533  //   #pragma omp simd collapse(2) ordered(2)
5534  //   for (i = 0; i < NI; ++i)
5535  //     for (k = 0; k < NK; ++k)
5536  //       for (j = J0; j < NJ; j+=2) {
5537  //         <loop body>
5538  //       }
5539  //
5540  // We generate the code below.
5541  // Note: the loop body may be outlined in CodeGen.
5542  // Note: some counters may be C++ classes, operator- is used to find number of
5543  // iterations and operator+= to calculate counter value.
5544  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
5545  // or i64 is currently supported).
5546  //
5547  //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
5548  //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
5549  //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
5550  //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
5551  //     // similar updates for vars in clauses (e.g. 'linear')
5552  //     <loop body (using local i and j)>
5553  //   }
5554  //   i = NI; // assign final values of counters
5555  //   j = NJ;
5556  //
5557
5558  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
5559  // the iteration counts of the collapsed for loops.
5560  // Precondition tests if there is at least one iteration (all conditions are
5561  // true).
5562  auto PreCond = ExprResult(IterSpaces[0].PreCond);
5563  Expr *N0 = IterSpaces[0].NumIterations;
5564  ExprResult LastIteration32 =
5565      widenIterationCount(/*Bits=*/32,
5566                          SemaRef
5567                              .PerformImplicitConversion(
5568                                  N0->IgnoreImpCasts(), N0->getType(),
5569                                  Sema::AA_Converting/*AllowExplicit=*/true)
5570                              .get(),
5571                          SemaRef);
5572  ExprResult LastIteration64 = widenIterationCount(
5573      /*Bits=*/64,
5574      SemaRef
5575          .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
5576                                     Sema::AA_Converting,
5577                                     /*AllowExplicit=*/true)
5578          .get(),
5579      SemaRef);
5580
5581  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
5582    return NestedLoopCount;
5583
5584  ASTContext &C = SemaRef.Context;
5585  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
5586
5587  Scope *CurScope = DSA.getCurScope();
5588  for (unsigned Cnt = 1Cnt < NestedLoopCount; ++Cnt) {
5589    if (PreCond.isUsable()) {
5590      PreCond =
5591          SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
5592                             PreCond.get(), IterSpaces[Cnt].PreCond);
5593    }
5594    Expr *N = IterSpaces[Cnt].NumIterations;
5595    SourceLocation Loc = N->getExprLoc();
5596    AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
5597    if (LastIteration32.isUsable())
5598      LastIteration32 = SemaRef.BuildBinOp(
5599          CurScopeLocBO_MulLastIteration32.get(),
5600          SemaRef
5601              .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
5602                                         Sema::AA_Converting,
5603                                         /*AllowExplicit=*/true)
5604              .get());
5605    if (LastIteration64.isUsable())
5606      LastIteration64 = SemaRef.BuildBinOp(
5607          CurScopeLocBO_MulLastIteration64.get(),
5608          SemaRef
5609              .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
5610                                         Sema::AA_Converting,
5611                                         /*AllowExplicit=*/true)
5612              .get());
5613  }
5614
5615  // Choose either the 32-bit or 64-bit version.
5616  ExprResult LastIteration = LastIteration64;
5617  if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
5618      (LastIteration32.isUsable() &&
5619       C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
5620       (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
5621        fitsInto(
5622            /*Bits=*/32,
5623            LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
5624            LastIteration64.get(), SemaRef))))
5625    LastIteration = LastIteration32;
5626  QualType VType = LastIteration.get()->getType();
5627  QualType RealVType = VType;
5628  QualType StrideVType = VType;
5629  if (isOpenMPTaskLoopDirective(DKind)) {
5630    VType =
5631        SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64/*Signed=*/0);
5632    StrideVType =
5633        SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64/*Signed=*/1);
5634  }
5635
5636  if (!LastIteration.isUsable())
5637    return 0;
5638
5639  // Save the number of iterations.
5640  ExprResult NumIterations = LastIteration;
5641  {
5642    LastIteration = SemaRef.BuildBinOp(
5643        CurScopeLastIteration.get()->getExprLoc(), BO_Sub,
5644        LastIteration.get(),
5645        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5646    if (!LastIteration.isUsable())
5647      return 0;
5648  }
5649
5650  // Calculate the last iteration number beforehand instead of doing this on
5651  // each iteration. Do not do this if the number of iterations may be kfold-ed.
5652  llvm::APSInt Result;
5653  bool IsConstant =
5654      LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
5655  ExprResult CalcLastIteration;
5656  if (!IsConstant) {
5657    ExprResult SaveRef =
5658        tryBuildCapture(SemaRef, LastIteration.get(), Captures);
5659    LastIteration = SaveRef;
5660
5661    // Prepare SaveRef + 1.
5662    NumIterations = SemaRef.BuildBinOp(
5663        CurScopeSaveRef.get()->getExprLoc(), BO_AddSaveRef.get(),
5664        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5665    if (!NumIterations.isUsable())
5666      return 0;
5667  }
5668
5669  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
5670
5671  // Build variables passed into runtime, necessary for worksharing directives.
5672  ExprResult LBUBILSTEUBCombLBCombUBPrevLBPrevUBCombEUB;
5673  if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
5674      isOpenMPDistributeDirective(DKind)) {
5675    // Lower bound variable, initialized with zero.
5676    VarDecl *LBDecl = buildVarDecl(SemaRefInitLocVType".omp.lb");
5677    LB = buildDeclRefExpr(SemaRefLBDeclVTypeInitLoc);
5678    SemaRef.AddInitializerToDecl(LBDecl,
5679                                 SemaRef.ActOnIntegerConstant(InitLoc0).get(),
5680                                 /*DirectInit*/ false);
5681
5682    // Upper bound variable, initialized with last iteration number.
5683    VarDecl *UBDecl = buildVarDecl(SemaRefInitLocVType".omp.ub");
5684    UB = buildDeclRefExpr(SemaRefUBDeclVTypeInitLoc);
5685    SemaRef.AddInitializerToDecl(UBDeclLastIteration.get(),
5686                                 /*DirectInit*/ false);
5687
5688    // A 32-bit variable-flag where runtime returns 1 for the last iteration.
5689    // This will be used to implement clause 'lastprivate'.
5690    QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32true);
5691    VarDecl *ILDecl = buildVarDecl(SemaRefInitLocInt32Ty".omp.is_last");
5692    IL = buildDeclRefExpr(SemaRefILDeclInt32TyInitLoc);
5693    SemaRef.AddInitializerToDecl(ILDecl,
5694                                 SemaRef.ActOnIntegerConstant(InitLoc0).get(),
5695                                 /*DirectInit*/ false);
5696
5697    // Stride variable returned by runtime (we initialize it to 1 by default).
5698    VarDecl *STDecl =
5699        buildVarDecl(SemaRefInitLocStrideVType".omp.stride");
5700    ST = buildDeclRefExpr(SemaRefSTDeclStrideVTypeInitLoc);
5701    SemaRef.AddInitializerToDecl(STDecl,
5702                                 SemaRef.ActOnIntegerConstant(InitLoc1).get(),
5703                                 /*DirectInit*/ false);
5704
5705    // Build expression: UB = min(UB, LastIteration)
5706    // It is necessary for CodeGen of directives with static scheduling.
5707    ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScopeInitLocBO_GT,
5708                                                UB.get(), LastIteration.get());
5709    ExprResult CondOp = SemaRef.ActOnConditionalOp(
5710        LastIteration.get()->getExprLoc(), InitLocIsUBGreater.get(),
5711        LastIteration.get(), UB.get());
5712    EUB = SemaRef.BuildBinOp(CurScopeInitLocBO_AssignUB.get(),
5713                             CondOp.get());
5714    EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
5715
5716    // If we have a combined directive that combines 'distribute', 'for' or
5717    // 'simd' we need to be able to access the bounds of the schedule of the
5718    // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
5719    // by scheduling 'distribute' have to be passed to the schedule of 'for'.
5720    if (isOpenMPLoopBoundSharingDirective(DKind)) {
5721      // Lower bound variable, initialized with zero.
5722      VarDecl *CombLBDecl =
5723          buildVarDecl(SemaRefInitLocVType".omp.comb.lb");
5724      CombLB = buildDeclRefExpr(SemaRefCombLBDeclVTypeInitLoc);
5725      SemaRef.AddInitializerToDecl(
5726          CombLBDeclSemaRef.ActOnIntegerConstant(InitLoc0).get(),
5727          /*DirectInit*/ false);
5728
5729      // Upper bound variable, initialized with last iteration number.
5730      VarDecl *CombUBDecl =
5731          buildVarDecl(SemaRefInitLocVType".omp.comb.ub");
5732      CombUB = buildDeclRefExpr(SemaRefCombUBDeclVTypeInitLoc);
5733      SemaRef.AddInitializerToDecl(CombUBDeclLastIteration.get(),
5734                                   /*DirectInit*/ false);
5735
5736      ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
5737          CurScopeInitLocBO_GTCombUB.get(), LastIteration.get());
5738      ExprResult CombCondOp =
5739          SemaRef.ActOnConditionalOp(InitLocInitLocCombIsUBGreater.get(),
5740                                     LastIteration.get(), CombUB.get());
5741      CombEUB = SemaRef.BuildBinOp(CurScopeInitLocBO_AssignCombUB.get(),
5742                                   CombCondOp.get());
5743      CombEUB =
5744          SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
5745
5746      const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5747      // We expect to have at least 2 more parameters than the 'parallel'
5748      // directive does - the lower and upper bounds of the previous schedule.
5749       (0) . __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 5750, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CD->getNumParams() >= 4 &&
5750 (0) . __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 5750, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">             "Unexpected number of parameters in loop combined directive");
5751
5752      // Set the proper type for the bounds given what we learned from the
5753      // enclosed loops.
5754      ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
5755      ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
5756
5757      // Previous lower and upper bounds are obtained from the region
5758      // parameters.
5759      PrevLB =
5760          buildDeclRefExpr(SemaRefPrevLBDeclPrevLBDecl->getType(), InitLoc);
5761      PrevUB =
5762          buildDeclRefExpr(SemaRefPrevUBDeclPrevUBDecl->getType(), InitLoc);
5763    }
5764  }
5765
5766  // Build the iteration variable and its initialization before loop.
5767  ExprResult IV;
5768  ExprResult InitCombInit;
5769  {
5770    VarDecl *IVDecl = buildVarDecl(SemaRefInitLocRealVType".omp.iv");
5771    IV = buildDeclRefExpr(SemaRefIVDeclRealVTypeInitLoc);
5772    Expr *RHS =
5773        (isOpenMPWorksharingDirective(DKind) ||
5774         isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
5775            ? LB.get()
5776            : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5777    Init = SemaRef.BuildBinOp(CurScopeInitLocBO_AssignIV.get(), RHS);
5778    Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
5779
5780    if (isOpenMPLoopBoundSharingDirective(DKind)) {
5781      Expr *CombRHS =
5782          (isOpenMPWorksharingDirective(DKind) ||
5783           isOpenMPTaskLoopDirective(DKind) ||
5784           isOpenMPDistributeDirective(DKind))
5785              ? CombLB.get()
5786              : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5787      CombInit =
5788          SemaRef.BuildBinOp(CurScopeInitLocBO_AssignIV.get(), CombRHS);
5789      CombInit =
5790          SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
5791    }
5792  }
5793
5794  bool UseStrictCompare =
5795      RealVType->hasUnsignedIntegerRepresentation() &&
5796      llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
5797        return LIS.IsStrictCompare;
5798      });
5799  // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
5800  // unsigned IV)) for worksharing loops.
5801  SourceLocation CondLoc = AStmt->getBeginLoc();
5802  Expr *BoundUB = UB.get();
5803  if (UseStrictCompare) {
5804    BoundUB =
5805        SemaRef
5806            .BuildBinOp(CurScopeCondLocBO_AddBoundUB,
5807                        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
5808            .get();
5809    BoundUB =
5810        SemaRef.ActOnFinishFullExpr(BoundUB/*DiscardedValue*/ false).get();
5811  }
5812  ExprResult Cond =
5813      (isOpenMPWorksharingDirective(DKind) ||
5814       isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
5815          ? SemaRef.BuildBinOp(CurScopeCondLoc,
5816                               UseStrictCompare ? BO_LT : BO_LEIV.get(),
5817                               BoundUB)
5818          : SemaRef.BuildBinOp(CurScopeCondLocBO_LTIV.get(),
5819                               NumIterations.get());
5820  ExprResult CombDistCond;
5821  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5822    CombDistCond = SemaRef.BuildBinOp(CurScopeCondLocBO_LTIV.get(),
5823                                      NumIterations.get());
5824  }
5825
5826  ExprResult CombCond;
5827  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5828    Expr *BoundCombUB = CombUB.get();
5829    if (UseStrictCompare) {
5830      BoundCombUB =
5831          SemaRef
5832              .BuildBinOp(
5833                  CurScopeCondLocBO_AddBoundCombUB,
5834                  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
5835              .get();
5836      BoundCombUB =
5837          SemaRef.ActOnFinishFullExpr(BoundCombUB/*DiscardedValue*/ false)
5838              .get();
5839    }
5840    CombCond =
5841        SemaRef.BuildBinOp(CurScopeCondLocUseStrictCompare ? BO_LT : BO_LE,
5842                           IV.get(), BoundCombUB);
5843  }
5844  // Loop increment (IV = IV + 1)
5845  SourceLocation IncLoc = AStmt->getBeginLoc();
5846  ExprResult Inc =
5847      SemaRef.BuildBinOp(CurScopeIncLocBO_AddIV.get(),
5848                         SemaRef.ActOnIntegerConstant(IncLoc1).get());
5849  if (!Inc.isUsable())
5850    return 0;
5851  Inc = SemaRef.BuildBinOp(CurScopeIncLocBO_AssignIV.get(), Inc.get());
5852  Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
5853  if (!Inc.isUsable())
5854    return 0;
5855
5856  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
5857  // Used for directives with static scheduling.
5858  // In combined construct, add combined version that use CombLB and CombUB
5859  // base variables for the update
5860  ExprResult NextLBNextUBCombNextLBCombNextUB;
5861  if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
5862      isOpenMPDistributeDirective(DKind)) {
5863    // LB + ST
5864    NextLB = SemaRef.BuildBinOp(CurScopeIncLocBO_AddLB.get(), ST.get());
5865    if (!NextLB.isUsable())
5866      return 0;
5867    // LB = LB + ST
5868    NextLB =
5869        SemaRef.BuildBinOp(CurScopeIncLocBO_AssignLB.get(), NextLB.get());
5870    NextLB =
5871        SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
5872    if (!NextLB.isUsable())
5873      return 0;
5874    // UB + ST
5875    NextUB = SemaRef.BuildBinOp(CurScopeIncLocBO_AddUB.get(), ST.get());
5876    if (!NextUB.isUsable())
5877      return 0;
5878    // UB = UB + ST
5879    NextUB =
5880        SemaRef.BuildBinOp(CurScopeIncLocBO_AssignUB.get(), NextUB.get());
5881    NextUB =
5882        SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
5883    if (!NextUB.isUsable())
5884      return 0;
5885    if (isOpenMPLoopBoundSharingDirective(DKind)) {
5886      CombNextLB =
5887          SemaRef.BuildBinOp(CurScopeIncLocBO_AddCombLB.get(), ST.get());
5888      if (!NextLB.isUsable())
5889        return 0;
5890      // LB = LB + ST
5891      CombNextLB = SemaRef.BuildBinOp(CurScopeIncLocBO_AssignCombLB.get(),
5892                                      CombNextLB.get());
5893      CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
5894                                               /*DiscardedValue*/ false);
5895      if (!CombNextLB.isUsable())
5896        return 0;
5897      // UB + ST
5898      CombNextUB =
5899          SemaRef.BuildBinOp(CurScopeIncLocBO_AddCombUB.get(), ST.get());
5900      if (!CombNextUB.isUsable())
5901        return 0;
5902      // UB = UB + ST
5903      CombNextUB = SemaRef.BuildBinOp(CurScopeIncLocBO_AssignCombUB.get(),
5904                                      CombNextUB.get());
5905      CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
5906                                               /*DiscardedValue*/ false);
5907      if (!CombNextUB.isUsable())
5908        return 0;
5909    }
5910  }
5911
5912  // Create increment expression for distribute loop when combined in a same
5913  // directive with for as IV = IV + ST; ensure upper bound expression based
5914  // on PrevUB instead of NumIterations - used to implement 'for' when found
5915  // in combination with 'distribute', like in 'distribute parallel for'
5916  SourceLocation DistIncLoc = AStmt->getBeginLoc();
5917  ExprResult DistCondDistIncPrevEUBParForInDistCond;
5918  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5919    DistCond = SemaRef.BuildBinOp(
5920        CurScopeCondLocUseStrictCompare ? BO_LT : BO_LEIV.get(), BoundUB);
5921     (0) . __assert_fail ("DistCond.isUsable() && \"distribute cond expr was not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 5921, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DistCond.isUsable() && "distribute cond expr was not built");
5922
5923    DistInc =
5924        SemaRef.BuildBinOp(CurScopeDistIncLocBO_AddIV.get(), ST.get());
5925     (0) . __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 5925, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DistInc.isUsable() && "distribute inc expr was not built");
5926    DistInc = SemaRef.BuildBinOp(CurScopeDistIncLocBO_AssignIV.get(),
5927                                 DistInc.get());
5928    DistInc =
5929        SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
5930     (0) . __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 5930, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DistInc.isUsable() && "distribute inc expr was not built");
5931
5932    // Build expression: UB = min(UB, prevUB) for #for in composite or combined
5933    // construct
5934    SourceLocation DistEUBLoc = AStmt->getBeginLoc();
5935    ExprResult IsUBGreater =
5936        SemaRef.BuildBinOp(CurScopeDistEUBLocBO_GTUB.get(), PrevUB.get());
5937    ExprResult CondOp = SemaRef.ActOnConditionalOp(
5938        DistEUBLocDistEUBLocIsUBGreater.get(), PrevUB.get(), UB.get());
5939    PrevEUB = SemaRef.BuildBinOp(CurScopeDistIncLocBO_AssignUB.get(),
5940                                 CondOp.get());
5941    PrevEUB =
5942        SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
5943
5944    // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
5945    // parallel for is in combination with a distribute directive with
5946    // schedule(static, 1)
5947    Expr *BoundPrevUB = PrevUB.get();
5948    if (UseStrictCompare) {
5949      BoundPrevUB =
5950          SemaRef
5951              .BuildBinOp(
5952                  CurScopeCondLocBO_AddBoundPrevUB,
5953                  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
5954              .get();
5955      BoundPrevUB =
5956          SemaRef.ActOnFinishFullExpr(BoundPrevUB/*DiscardedValue*/ false)
5957              .get();
5958    }
5959    ParForInDistCond =
5960        SemaRef.BuildBinOp(CurScopeCondLocUseStrictCompare ? BO_LT : BO_LE,
5961                           IV.get(), BoundPrevUB);
5962  }
5963
5964  // Build updates and final values of the loop counters.
5965  bool HasErrors = false;
5966  Built.Counters.resize(NestedLoopCount);
5967  Built.Inits.resize(NestedLoopCount);
5968  Built.Updates.resize(NestedLoopCount);
5969  Built.Finals.resize(NestedLoopCount);
5970  {
5971    // We implement the following algorithm for obtaining the
5972    // original loop iteration variable values based on the
5973    // value of the collapsed loop iteration variable IV.
5974    //
5975    // Let n+1 be the number of collapsed loops in the nest.
5976    // Iteration variables (I0, I1, .... In)
5977    // Iteration counts (N0, N1, ... Nn)
5978    //
5979    // Acc = IV;
5980    //
5981    // To compute Ik for loop k, 0 <= k <= n, generate:
5982    //    Prod = N(k+1) * N(k+2) * ... * Nn;
5983    //    Ik = Acc / Prod;
5984    //    Acc -= Ik * Prod;
5985    //
5986    ExprResult Acc = IV;
5987    for (unsigned int Cnt = 0Cnt < NestedLoopCount; ++Cnt) {
5988      LoopIterationSpace &IS = IterSpaces[Cnt];
5989      SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
5990      ExprResult Iter;
5991
5992      // Compute prod
5993      ExprResult Prod =
5994          SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
5995      for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
5996        Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
5997                                  IterSpaces[K].NumIterations);
5998
5999      // Iter = Acc / Prod
6000      // If there is at least one more inner loop to avoid
6001      // multiplication by 1.
6002      if (Cnt + 1 < NestedLoopCount)
6003        Iter = SemaRef.BuildBinOp(CurScopeUpdLocBO_Div,
6004                                  Acc.get(), Prod.get());
6005      else
6006        Iter = Acc;
6007      if (!Iter.isUsable()) {
6008        HasErrors = true;
6009        break;
6010      }
6011
6012      // Update Acc:
6013      // Acc -= Iter * Prod
6014      // Check if there is at least one more inner loop to avoid
6015      // multiplication by 1.
6016      if (Cnt + 1 < NestedLoopCount)
6017        Prod = SemaRef.BuildBinOp(CurScopeUpdLocBO_Mul,
6018                                  Iter.get(), Prod.get());
6019      else
6020        Prod = Iter;
6021      Acc = SemaRef.BuildBinOp(CurScopeUpdLocBO_Sub,
6022                               Acc.get(), Prod.get());
6023
6024      // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
6025      auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
6026      DeclRefExpr *CounterVar = buildDeclRefExpr(
6027          SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
6028          /*RefersToCapture=*/true);
6029      ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
6030                                         IS.CounterInit, Captures);
6031      if (!Init.isUsable()) {
6032        HasErrors = true;
6033        break;
6034      }
6035      ExprResult Update = buildCounterUpdate(
6036          SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
6037          IS.CounterStep, IS.Subtract, &Captures);
6038      if (!Update.isUsable()) {
6039        HasErrors = true;
6040        break;
6041      }
6042
6043      // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
6044      ExprResult Final = buildCounterUpdate(
6045          SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
6046          IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
6047      if (!Final.isUsable()) {
6048        HasErrors = true;
6049        break;
6050      }
6051
6052      if (!Update.isUsable() || !Final.isUsable()) {
6053        HasErrors = true;
6054        break;
6055      }
6056      // Save results
6057      Built.Counters[Cnt] = IS.CounterVar;
6058      Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
6059      Built.Inits[Cnt] = Init.get();
6060      Built.Updates[Cnt] = Update.get();
6061      Built.Finals[Cnt] = Final.get();
6062    }
6063  }
6064
6065  if (HasErrors)
6066    return 0;
6067
6068  // Save results
6069  Built.IterationVarRef = IV.get();
6070  Built.LastIteration = LastIteration.get();
6071  Built.NumIterations = NumIterations.get();
6072  Built.CalcLastIteration = SemaRef
6073                                .ActOnFinishFullExpr(CalcLastIteration.get(),
6074                                                     /*DiscardedValue*/ false)
6075                                .get();
6076  Built.PreCond = PreCond.get();
6077  Built.PreInits = buildPreInits(C, Captures);
6078  Built.Cond = Cond.get();
6079  Built.Init = Init.get();
6080  Built.Inc = Inc.get();
6081  Built.LB = LB.get();
6082  Built.UB = UB.get();
6083  Built.IL = IL.get();
6084  Built.ST = ST.get();
6085  Built.EUB = EUB.get();
6086  Built.NLB = NextLB.get();
6087  Built.NUB = NextUB.get();
6088  Built.PrevLB = PrevLB.get();
6089  Built.PrevUB = PrevUB.get();
6090  Built.DistInc = DistInc.get();
6091  Built.PrevEUB = PrevEUB.get();
6092  Built.DistCombinedFields.LB = CombLB.get();
6093  Built.DistCombinedFields.UB = CombUB.get();
6094  Built.DistCombinedFields.EUB = CombEUB.get();
6095  Built.DistCombinedFields.Init = CombInit.get();
6096  Built.DistCombinedFields.Cond = CombCond.get();
6097  Built.DistCombinedFields.NLB = CombNextLB.get();
6098  Built.DistCombinedFields.NUB = CombNextUB.get();
6099  Built.DistCombinedFields.DistCond = CombDistCond.get();
6100  Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
6101
6102  return NestedLoopCount;
6103}
6104
6105static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
6106  auto CollapseClauses =
6107      OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
6108  if (CollapseClauses.begin() != CollapseClauses.end())
6109    return (*CollapseClauses.begin())->getNumForLoops();
6110  return nullptr;
6111}
6112
6113static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
6114  auto OrderedClauses =
6115      OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
6116  if (OrderedClauses.begin() != OrderedClauses.end())
6117    return (*OrderedClauses.begin())->getNumForLoops();
6118  return nullptr;
6119}
6120
6121static bool checkSimdlenSafelenSpecified(Sema &S,
6122                                         const ArrayRef<OMPClause *> Clauses) {
6123  const OMPSafelenClause *Safelen = nullptr;
6124  const OMPSimdlenClause *Simdlen = nullptr;
6125
6126  for (const OMPClause *Clause : Clauses) {
6127    if (Clause->getClauseKind() == OMPC_safelen)
6128      Safelen = cast<OMPSafelenClause>(Clause);
6129    else if (Clause->getClauseKind() == OMPC_simdlen)
6130      Simdlen = cast<OMPSimdlenClause>(Clause);
6131    if (Safelen && Simdlen)
6132      break;
6133  }
6134
6135  if (Simdlen && Safelen) {
6136    const Expr *SimdlenLength = Simdlen->getSimdlen();
6137    const Expr *SafelenLength = Safelen->getSafelen();
6138    if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
6139        SimdlenLength->isInstantiationDependent() ||
6140        SimdlenLength->containsUnexpandedParameterPack())
6141      return false;
6142    if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
6143        SafelenLength->isInstantiationDependent() ||
6144        SafelenLength->containsUnexpandedParameterPack())
6145      return false;
6146    Expr::EvalResult SimdlenResultSafelenResult;
6147    SimdlenLength->EvaluateAsInt(SimdlenResultS.Context);
6148    SafelenLength->EvaluateAsInt(SafelenResultS.Context);
6149    llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
6150    llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
6151    // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
6152    // If both simdlen and safelen clauses are specified, the value of the
6153    // simdlen parameter must be less than or equal to the value of the safelen
6154    // parameter.
6155    if (SimdlenRes > SafelenRes) {
6156      S.Diag(SimdlenLength->getExprLoc(),
6157             diag::err_omp_wrong_simdlen_safelen_values)
6158          << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
6159      return true;
6160    }
6161  }
6162  return false;
6163}
6164
6165StmtResult
6166Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> ClausesStmt *AStmt,
6167                               SourceLocation StartLocSourceLocation EndLoc,
6168                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6169  if (!AStmt)
6170    return StmtError();
6171
6172   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6172, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6173  OMPLoopDirective::HelperExprs B;
6174  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6175  // define the nested loops number.
6176  unsigned NestedLoopCount = checkOpenMPLoop(
6177      OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
6178      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
6179  if (NestedLoopCount == 0)
6180    return StmtError();
6181
6182   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6183, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
6183 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6183, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp simd loop exprs were not built");
6184
6185  if (!CurContext->isDependentContext()) {
6186    // Finalize the clauses that need pre-built expressions for CodeGen.
6187    for (OMPClause *C : Clauses) {
6188      if (auto *LC = dyn_cast<OMPLinearClause>(C))
6189        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6190                                     B.NumIterations, *this, CurScope,
6191                                     DSAStack))
6192          return StmtError();
6193    }
6194  }
6195
6196  if (checkSimdlenSafelenSpecified(*this, Clauses))
6197    return StmtError();
6198
6199  setFunctionHasBranchProtectedScope();
6200  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
6201                                  Clauses, AStmt, B);
6202}
6203
6204StmtResult
6205Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> ClausesStmt *AStmt,
6206                              SourceLocation StartLocSourceLocation EndLoc,
6207                              VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6208  if (!AStmt)
6209    return StmtError();
6210
6211   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6211, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6212  OMPLoopDirective::HelperExprs B;
6213  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6214  // define the nested loops number.
6215  unsigned NestedLoopCount = checkOpenMPLoop(
6216      OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
6217      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
6218  if (NestedLoopCount == 0)
6219    return StmtError();
6220
6221   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6222, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
6222 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6222, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for loop exprs were not built");
6223
6224  if (!CurContext->isDependentContext()) {
6225    // Finalize the clauses that need pre-built expressions for CodeGen.
6226    for (OMPClause *C : Clauses) {
6227      if (auto *LC = dyn_cast<OMPLinearClause>(C))
6228        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6229                                     B.NumIterations, *this, CurScope,
6230                                     DSAStack))
6231          return StmtError();
6232    }
6233  }
6234
6235  setFunctionHasBranchProtectedScope();
6236  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
6237                                 Clauses, AStmt, B, DSAStack->isCancelRegion());
6238}
6239
6240StmtResult Sema::ActOnOpenMPForSimdDirective(
6241    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
6242    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6243  if (!AStmt)
6244    return StmtError();
6245
6246   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6246, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6247  OMPLoopDirective::HelperExprs B;
6248  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6249  // define the nested loops number.
6250  unsigned NestedLoopCount =
6251      checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
6252                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6253                      VarsWithImplicitDSA, B);
6254  if (NestedLoopCount == 0)
6255    return StmtError();
6256
6257   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6258, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
6258 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6258, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for simd loop exprs were not built");
6259
6260  if (!CurContext->isDependentContext()) {
6261    // Finalize the clauses that need pre-built expressions for CodeGen.
6262    for (OMPClause *C : Clauses) {
6263      if (auto *LC = dyn_cast<OMPLinearClause>(C))
6264        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6265                                     B.NumIterations, *this, CurScope,
6266                                     DSAStack))
6267          return StmtError();
6268    }
6269  }
6270
6271  if (checkSimdlenSafelenSpecified(*this, Clauses))
6272    return StmtError();
6273
6274  setFunctionHasBranchProtectedScope();
6275  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
6276                                     Clauses, AStmt, B);
6277}
6278
6279StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
6280                                              Stmt *AStmt,
6281                                              SourceLocation StartLoc,
6282                                              SourceLocation EndLoc) {
6283  if (!AStmt)
6284    return StmtError();
6285
6286   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6286, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6287  auto BaseStmt = AStmt;
6288  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
6289    BaseStmt = CS->getCapturedStmt();
6290  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
6291    auto S = C->children();
6292    if (S.begin() == S.end())
6293      return StmtError();
6294    // All associated statements must be '#pragma omp section' except for
6295    // the first one.
6296    for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
6297      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6298        if (SectionStmt)
6299          Diag(SectionStmt->getBeginLoc(),
6300               diag::err_omp_sections_substmt_not_section);
6301        return StmtError();
6302      }
6303      cast<OMPSectionDirective>(SectionStmt)
6304          ->setHasCancel(DSAStack->isCancelRegion());
6305    }
6306  } else {
6307    Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
6308    return StmtError();
6309  }
6310
6311  setFunctionHasBranchProtectedScope();
6312
6313  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6314                                      DSAStack->isCancelRegion());
6315}
6316
6317StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
6318                                             SourceLocation StartLoc,
6319                                             SourceLocation EndLoc) {
6320  if (!AStmt)
6321    return StmtError();
6322
6323   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6323, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6324
6325  setFunctionHasBranchProtectedScope();
6326  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
6327
6328  return OMPSectionDirective::Create(ContextStartLocEndLocAStmt,
6329                                     DSAStack->isCancelRegion());
6330}
6331
6332StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
6333                                            Stmt *AStmt,
6334                                            SourceLocation StartLoc,
6335                                            SourceLocation EndLoc) {
6336  if (!AStmt)
6337    return StmtError();
6338
6339   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6339, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6340
6341  setFunctionHasBranchProtectedScope();
6342
6343  // OpenMP [2.7.3, single Construct, Restrictions]
6344  // The copyprivate clause must not be used with the nowait clause.
6345  const OMPClause *Nowait = nullptr;
6346  const OMPClause *Copyprivate = nullptr;
6347  for (const OMPClause *Clause : Clauses) {
6348    if (Clause->getClauseKind() == OMPC_nowait)
6349      Nowait = Clause;
6350    else if (Clause->getClauseKind() == OMPC_copyprivate)
6351      Copyprivate = Clause;
6352    if (Copyprivate && Nowait) {
6353      Diag(Copyprivate->getBeginLoc(),
6354           diag::err_omp_single_copyprivate_with_nowait);
6355      Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
6356      return StmtError();
6357    }
6358  }
6359
6360  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6361}
6362
6363StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
6364                                            SourceLocation StartLoc,
6365                                            SourceLocation EndLoc) {
6366  if (!AStmt)
6367    return StmtError();
6368
6369   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6369, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6370
6371  setFunctionHasBranchProtectedScope();
6372
6373  return OMPMasterDirective::Create(ContextStartLocEndLocAStmt);
6374}
6375
6376StmtResult Sema::ActOnOpenMPCriticalDirective(
6377    const DeclarationNameInfo &DirNameArrayRef<OMPClause *> Clauses,
6378    Stmt *AStmtSourceLocation StartLocSourceLocation EndLoc) {
6379  if (!AStmt)
6380    return StmtError();
6381
6382   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6382, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6383
6384  bool ErrorFound = false;
6385  llvm::APSInt Hint;
6386  SourceLocation HintLoc;
6387  bool DependentHint = false;
6388  for (const OMPClause *C : Clauses) {
6389    if (C->getClauseKind() == OMPC_hint) {
6390      if (!DirName.getName()) {
6391        Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
6392        ErrorFound = true;
6393      }
6394      Expr *E = cast<OMPHintClause>(C)->getHint();
6395      if (E->isTypeDependent() || E->isValueDependent() ||
6396          E->isInstantiationDependent()) {
6397        DependentHint = true;
6398      } else {
6399        Hint = E->EvaluateKnownConstInt(Context);
6400        HintLoc = C->getBeginLoc();
6401      }
6402    }
6403  }
6404  if (ErrorFound)
6405    return StmtError();
6406  const auto Pair = DSAStack->getCriticalWithHint(DirName);
6407  if (Pair.first && DirName.getName() && !DependentHint) {
6408    if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
6409      Diag(StartLoc, diag::err_omp_critical_with_hint);
6410      if (HintLoc.isValid())
6411        Diag(HintLoc, diag::note_omp_critical_hint_here)
6412            << 0 << Hint.toString(/*Radix=*/10/*Signed=*/false);
6413      else
6414        Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
6415      if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
6416        Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
6417            << 1
6418            << C->getHint()->EvaluateKnownConstInt(Context).toString(
6419                   /*Radix=*/10/*Signed=*/false);
6420      } else {
6421        Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
6422      }
6423    }
6424  }
6425
6426  setFunctionHasBranchProtectedScope();
6427
6428  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
6429                                           Clauses, AStmt);
6430  if (!Pair.first && DirName.getName() && !DependentHint)
6431    DSAStack->addCriticalWithHint(Dir, Hint);
6432  return Dir;
6433}
6434
6435StmtResult Sema::ActOnOpenMPParallelForDirective(
6436    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
6437    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6438  if (!AStmt)
6439    return StmtError();
6440
6441  auto *CS = cast<CapturedStmt>(AStmt);
6442  // 1.2.2 OpenMP Language Terminology
6443  // Structured block - An executable statement with a single entry at the
6444  // top and a single exit at the bottom.
6445  // The point of exit cannot be a branch out of the structured block.
6446  // longjmp() and throw() must not violate the entry/exit criteria.
6447  CS->getCapturedDecl()->setNothrow();
6448
6449  OMPLoopDirective::HelperExprs B;
6450  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6451  // define the nested loops number.
6452  unsigned NestedLoopCount =
6453      checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
6454                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6455                      VarsWithImplicitDSA, B);
6456  if (NestedLoopCount == 0)
6457    return StmtError();
6458
6459   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6460, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
6460 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6460, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp parallel for loop exprs were not built");
6461
6462  if (!CurContext->isDependentContext()) {
6463    // Finalize the clauses that need pre-built expressions for CodeGen.
6464    for (OMPClause *C : Clauses) {
6465      if (auto *LC = dyn_cast<OMPLinearClause>(C))
6466        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6467                                     B.NumIterations, *this, CurScope,
6468                                     DSAStack))
6469          return StmtError();
6470    }
6471  }
6472
6473  setFunctionHasBranchProtectedScope();
6474  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
6475                                         NestedLoopCount, Clauses, AStmt, B,
6476                                         DSAStack->isCancelRegion());
6477}
6478
6479StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
6480    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
6481    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6482  if (!AStmt)
6483    return StmtError();
6484
6485  auto *CS = cast<CapturedStmt>(AStmt);
6486  // 1.2.2 OpenMP Language Terminology
6487  // Structured block - An executable statement with a single entry at the
6488  // top and a single exit at the bottom.
6489  // The point of exit cannot be a branch out of the structured block.
6490  // longjmp() and throw() must not violate the entry/exit criteria.
6491  CS->getCapturedDecl()->setNothrow();
6492
6493  OMPLoopDirective::HelperExprs B;
6494  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6495  // define the nested loops number.
6496  unsigned NestedLoopCount =
6497      checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
6498                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6499                      VarsWithImplicitDSA, B);
6500  if (NestedLoopCount == 0)
6501    return StmtError();
6502
6503  if (!CurContext->isDependentContext()) {
6504    // Finalize the clauses that need pre-built expressions for CodeGen.
6505    for (OMPClause *C : Clauses) {
6506      if (auto *LC = dyn_cast<OMPLinearClause>(C))
6507        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6508                                     B.NumIterations, *this, CurScope,
6509                                     DSAStack))
6510          return StmtError();
6511    }
6512  }
6513
6514  if (checkSimdlenSafelenSpecified(*this, Clauses))
6515    return StmtError();
6516
6517  setFunctionHasBranchProtectedScope();
6518  return OMPParallelForSimdDirective::Create(
6519      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6520}
6521
6522StmtResult
6523Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
6524                                           Stmt *AStmtSourceLocation StartLoc,
6525                                           SourceLocation EndLoc) {
6526  if (!AStmt)
6527    return StmtError();
6528
6529   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6529, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6530  auto BaseStmt = AStmt;
6531  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
6532    BaseStmt = CS->getCapturedStmt();
6533  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
6534    auto S = C->children();
6535    if (S.begin() == S.end())
6536      return StmtError();
6537    // All associated statements must be '#pragma omp section' except for
6538    // the first one.
6539    for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
6540      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6541        if (SectionStmt)
6542          Diag(SectionStmt->getBeginLoc(),
6543               diag::err_omp_parallel_sections_substmt_not_section);
6544        return StmtError();
6545      }
6546      cast<OMPSectionDirective>(SectionStmt)
6547          ->setHasCancel(DSAStack->isCancelRegion());
6548    }
6549  } else {
6550    Diag(AStmt->getBeginLoc(),
6551         diag::err_omp_parallel_sections_not_compound_stmt);
6552    return StmtError();
6553  }
6554
6555  setFunctionHasBranchProtectedScope();
6556
6557  return OMPParallelSectionsDirective::Create(
6558      Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
6559}
6560
6561StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
6562                                          Stmt *AStmtSourceLocation StartLoc,
6563                                          SourceLocation EndLoc) {
6564  if (!AStmt)
6565    return StmtError();
6566
6567  auto *CS = cast<CapturedStmt>(AStmt);
6568  // 1.2.2 OpenMP Language Terminology
6569  // Structured block - An executable statement with a single entry at the
6570  // top and a single exit at the bottom.
6571  // The point of exit cannot be a branch out of the structured block.
6572  // longjmp() and throw() must not violate the entry/exit criteria.
6573  CS->getCapturedDecl()->setNothrow();
6574
6575  setFunctionHasBranchProtectedScope();
6576
6577  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6578                                  DSAStack->isCancelRegion());
6579}
6580
6581StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
6582                                               SourceLocation EndLoc) {
6583  return OMPTaskyieldDirective::Create(ContextStartLocEndLoc);
6584}
6585
6586StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
6587                                             SourceLocation EndLoc) {
6588  return OMPBarrierDirective::Create(ContextStartLocEndLoc);
6589}
6590
6591StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
6592                                              SourceLocation EndLoc) {
6593  return OMPTaskwaitDirective::Create(ContextStartLocEndLoc);
6594}
6595
6596StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
6597                                               Stmt *AStmt,
6598                                               SourceLocation StartLoc,
6599                                               SourceLocation EndLoc) {
6600  if (!AStmt)
6601    return StmtError();
6602
6603   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6603, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6604
6605  setFunctionHasBranchProtectedScope();
6606
6607  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
6608                                       AStmt,
6609                                       DSAStack->getTaskgroupReductionRef());
6610}
6611
6612StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
6613                                           SourceLocation StartLoc,
6614                                           SourceLocation EndLoc) {
6615   (0) . __assert_fail ("Clauses.size() <= 1 && \"Extra clauses in flush directive\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6615, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
6616  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
6617}
6618
6619StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
6620                                             Stmt *AStmt,
6621                                             SourceLocation StartLoc,
6622                                             SourceLocation EndLoc) {
6623  const OMPClause *DependFound = nullptr;
6624  const OMPClause *DependSourceClause = nullptr;
6625  const OMPClause *DependSinkClause = nullptr;
6626  bool ErrorFound = false;
6627  const OMPThreadsClause *TC = nullptr;
6628  const OMPSIMDClause *SC = nullptr;
6629  for (const OMPClause *C : Clauses) {
6630    if (auto *DC = dyn_cast<OMPDependClause>(C)) {
6631      DependFound = C;
6632      if (DC->getDependencyKind() == OMPC_DEPEND_source) {
6633        if (DependSourceClause) {
6634          Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
6635              << getOpenMPDirectiveName(OMPD_ordered)
6636              << getOpenMPClauseName(OMPC_depend) << 2;
6637          ErrorFound = true;
6638        } else {
6639          DependSourceClause = C;
6640        }
6641        if (DependSinkClause) {
6642          Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6643              << 0;
6644          ErrorFound = true;
6645        }
6646      } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
6647        if (DependSourceClause) {
6648          Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6649              << 1;
6650          ErrorFound = true;
6651        }
6652        DependSinkClause = C;
6653      }
6654    } else if (C->getClauseKind() == OMPC_threads) {
6655      TC = cast<OMPThreadsClause>(C);
6656    } else if (C->getClauseKind() == OMPC_simd) {
6657      SC = cast<OMPSIMDClause>(C);
6658    }
6659  }
6660  if (!ErrorFound && !SC &&
6661      isOpenMPSimdDirective(DSAStack->getParentDirective())) {
6662    // OpenMP [2.8.1,simd Construct, Restrictions]
6663    // An ordered construct with the simd clause is the only OpenMP construct
6664    // that can appear in the simd region.
6665    Diag(StartLoc, diag::err_omp_prohibited_region_simd);
6666    ErrorFound = true;
6667  } else if (DependFound && (TC || SC)) {
6668    Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
6669        << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
6670    ErrorFound = true;
6671  } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
6672    Diag(DependFound->getBeginLoc(),
6673         diag::err_omp_ordered_directive_without_param);
6674    ErrorFound = true;
6675  } else if (TC || Clauses.empty()) {
6676    if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
6677      SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
6678      Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
6679          << (TC != nullptr);
6680      Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
6681      ErrorFound = true;
6682    }
6683  }
6684  if ((!AStmt && !DependFound) || ErrorFound)
6685    return StmtError();
6686
6687  if (AStmt) {
6688     (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 6688, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6689
6690    setFunctionHasBranchProtectedScope();
6691  }
6692
6693  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6694}
6695
6696namespace {
6697/// Helper class for checking expression in 'omp atomic [update]'
6698/// construct.
6699class OpenMPAtomicUpdateChecker {
6700  /// Error results for atomic update expressions.
6701  enum ExprAnalysisErrorCode {
6702    /// A statement is not an expression statement.
6703    NotAnExpression,
6704    /// Expression is not builtin binary or unary operation.
6705    NotABinaryOrUnaryExpression,
6706    /// Unary operation is not post-/pre- increment/decrement operation.
6707    NotAnUnaryIncDecExpression,
6708    /// An expression is not of scalar type.
6709    NotAScalarType,
6710    /// A binary operation is not an assignment operation.
6711    NotAnAssignmentOp,
6712    /// RHS part of the binary operation is not a binary expression.
6713    NotABinaryExpression,
6714    /// RHS part is not additive/multiplicative/shift/biwise binary
6715    /// expression.
6716    NotABinaryOperator,
6717    /// RHS binary operation does not have reference to the updated LHS
6718    /// part.
6719    NotAnUpdateExpression,
6720    /// No errors is found.
6721    NoError
6722  };
6723  /// Reference to Sema.
6724  Sema &SemaRef;
6725  /// A location for note diagnostics (when error is found).
6726  SourceLocation NoteLoc;
6727  /// 'x' lvalue part of the source atomic expression.
6728  Expr *X;
6729  /// 'expr' rvalue part of the source atomic expression.
6730  Expr *E;
6731  /// Helper expression of the form
6732  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6733  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6734  Expr *UpdateExpr;
6735  /// Is 'x' a LHS in a RHS part of full update expression. It is
6736  /// important for non-associative operations.
6737  bool IsXLHSInRHSPart;
6738  BinaryOperatorKind Op;
6739  SourceLocation OpLoc;
6740  /// true if the source expression is a postfix unary operation, false
6741  /// if it is a prefix unary operation.
6742  bool IsPostfixUpdate;
6743
6744public:
6745  OpenMPAtomicUpdateChecker(Sema &SemaRef)
6746      : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
6747        IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
6748  /// Check specified statement that it is suitable for 'atomic update'
6749  /// constructs and extract 'x', 'expr' and Operation from the original
6750  /// expression. If DiagId and NoteId == 0, then only check is performed
6751  /// without error notification.
6752  /// \param DiagId Diagnostic which should be emitted if error is found.
6753  /// \param NoteId Diagnostic note for the main error message.
6754  /// \return true if statement is not an update expression, false otherwise.
6755  bool checkStatement(Stmt *Sunsigned DiagId = 0unsigned NoteId = 0);
6756  /// Return the 'x' lvalue part of the source atomic expression.
6757  Expr *getX() const { return X; }
6758  /// Return the 'expr' rvalue part of the source atomic expression.
6759  Expr *getExpr() const { return E; }
6760  /// Return the update expression used in calculation of the updated
6761  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6762  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6763  Expr *getUpdateExpr() const { return UpdateExpr; }
6764  /// Return true if 'x' is LHS in RHS part of full update expression,
6765  /// false otherwise.
6766  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
6767
6768  /// true if the source expression is a postfix unary operation, false
6769  /// if it is a prefix unary operation.
6770  bool isPostfixUpdate() const { return IsPostfixUpdate; }
6771
6772private:
6773  bool checkBinaryOperation(BinaryOperator *AtomicBinOpunsigned DiagId = 0,
6774                            unsigned NoteId = 0);
6775};
6776// namespace
6777
6778bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6779    BinaryOperator *AtomicBinOpunsigned DiagIdunsigned NoteId) {
6780  ExprAnalysisErrorCode ErrorFound = NoError;
6781  SourceLocation ErrorLocNoteLoc;
6782  SourceRange ErrorRangeNoteRange;
6783  // Allowed constructs are:
6784  //  x = x binop expr;
6785  //  x = expr binop x;
6786  if (AtomicBinOp->getOpcode() == BO_Assign) {
6787    X = AtomicBinOp->getLHS();
6788    if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6789            AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
6790      if (AtomicInnerBinOp->isMultiplicativeOp() ||
6791          AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6792          AtomicInnerBinOp->isBitwiseOp()) {
6793        Op = AtomicInnerBinOp->getOpcode();
6794        OpLoc = AtomicInnerBinOp->getOperatorLoc();
6795        Expr *LHS = AtomicInnerBinOp->getLHS();
6796        Expr *RHS = AtomicInnerBinOp->getRHS();
6797        llvm::FoldingSetNodeID XIdLHSIdRHSId;
6798        X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
6799                                          /*Canonical=*/true);
6800        LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
6801                                            /*Canonical=*/true);
6802        RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
6803                                            /*Canonical=*/true);
6804        if (XId == LHSId) {
6805          E = RHS;
6806          IsXLHSInRHSPart = true;
6807        } else if (XId == RHSId) {
6808          E = LHS;
6809          IsXLHSInRHSPart = false;
6810        } else {
6811          ErrorLoc = AtomicInnerBinOp->getExprLoc();
6812          ErrorRange = AtomicInnerBinOp->getSourceRange();
6813          NoteLoc = X->getExprLoc();
6814          NoteRange = X->getSourceRange();
6815          ErrorFound = NotAnUpdateExpression;
6816        }
6817      } else {
6818        ErrorLoc = AtomicInnerBinOp->getExprLoc();
6819        ErrorRange = AtomicInnerBinOp->getSourceRange();
6820        NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6821        NoteRange = SourceRange(NoteLocNoteLoc);
6822        ErrorFound = NotABinaryOperator;
6823      }
6824    } else {
6825      NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
6826      NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
6827      ErrorFound = NotABinaryExpression;
6828    }
6829  } else {
6830    ErrorLoc = AtomicBinOp->getExprLoc();
6831    ErrorRange = AtomicBinOp->getSourceRange();
6832    NoteLoc = AtomicBinOp->getOperatorLoc();
6833    NoteRange = SourceRange(NoteLocNoteLoc);
6834    ErrorFound = NotAnAssignmentOp;
6835  }
6836  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6837    SemaRef.Diag(ErrorLocDiagId) << ErrorRange;
6838    SemaRef.Diag(NoteLocNoteId) << ErrorFound << NoteRange;
6839    return true;
6840  }
6841  if (SemaRef.CurContext->isDependentContext())
6842    E = X = UpdateExpr = nullptr;
6843  return ErrorFound != NoError;
6844}
6845
6846bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *Sunsigned DiagId,
6847                                               unsigned NoteId) {
6848  ExprAnalysisErrorCode ErrorFound = NoError;
6849  SourceLocation ErrorLocNoteLoc;
6850  SourceRange ErrorRangeNoteRange;
6851  // Allowed constructs are:
6852  //  x++;
6853  //  x--;
6854  //  ++x;
6855  //  --x;
6856  //  x binop= expr;
6857  //  x = x binop expr;
6858  //  x = expr binop x;
6859  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
6860    AtomicBody = AtomicBody->IgnoreParenImpCasts();
6861    if (AtomicBody->getType()->isScalarType() ||
6862        AtomicBody->isInstantiationDependent()) {
6863      if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6864              AtomicBody->IgnoreParenImpCasts())) {
6865        // Check for Compound Assignment Operation
6866        Op = BinaryOperator::getOpForCompoundAssignment(
6867            AtomicCompAssignOp->getOpcode());
6868        OpLoc = AtomicCompAssignOp->getOperatorLoc();
6869        E = AtomicCompAssignOp->getRHS();
6870        X = AtomicCompAssignOp->getLHS()->IgnoreParens();
6871        IsXLHSInRHSPart = true;
6872      } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6873                     AtomicBody->IgnoreParenImpCasts())) {
6874        // Check for Binary Operation
6875        if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6876          return true;
6877      } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
6878                     AtomicBody->IgnoreParenImpCasts())) {
6879        // Check for Unary Operation
6880        if (AtomicUnaryOp->isIncrementDecrementOp()) {
6881          IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6882          Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6883          OpLoc = AtomicUnaryOp->getOperatorLoc();
6884          X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
6885          E = SemaRef.ActOnIntegerConstant(OpLoc/*uint64_t Val=*/1).get();
6886          IsXLHSInRHSPart = true;
6887        } else {
6888          ErrorFound = NotAnUnaryIncDecExpression;
6889          ErrorLoc = AtomicUnaryOp->getExprLoc();
6890          ErrorRange = AtomicUnaryOp->getSourceRange();
6891          NoteLoc = AtomicUnaryOp->getOperatorLoc();
6892          NoteRange = SourceRange(NoteLocNoteLoc);
6893        }
6894      } else if (!AtomicBody->isInstantiationDependent()) {
6895        ErrorFound = NotABinaryOrUnaryExpression;
6896        NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6897        NoteRange = ErrorRange = AtomicBody->getSourceRange();
6898      }
6899    } else {
6900      ErrorFound = NotAScalarType;
6901      NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
6902      NoteRange = ErrorRange = SourceRange(NoteLocNoteLoc);
6903    }
6904  } else {
6905    ErrorFound = NotAnExpression;
6906    NoteLoc = ErrorLoc = S->getBeginLoc();
6907    NoteRange = ErrorRange = SourceRange(NoteLocNoteLoc);
6908  }
6909  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6910    SemaRef.Diag(ErrorLocDiagId) << ErrorRange;
6911    SemaRef.Diag(NoteLocNoteId) << ErrorFound << NoteRange;
6912    return true;
6913  }
6914  if (SemaRef.CurContext->isDependentContext())
6915    E = X = UpdateExpr = nullptr;
6916  if (ErrorFound == NoError && E && X) {
6917    // Build an update expression of form 'OpaqueValueExpr(x) binop
6918    // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
6919    // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
6920    auto *OVEX = new (SemaRef.getASTContext())
6921        OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
6922    auto *OVEExpr = new (SemaRef.getASTContext())
6923        OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
6924    ExprResult Update =
6925        SemaRef.CreateBuiltinBinOp(OpLocOpIsXLHSInRHSPart ? OVEX : OVEExpr,
6926                                   IsXLHSInRHSPart ? OVEExpr : OVEX);
6927    if (Update.isInvalid())
6928      return true;
6929    Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
6930                                               Sema::AA_Casting);
6931    if (Update.isInvalid())
6932      return true;
6933    UpdateExpr = Update.get();
6934  }
6935  return ErrorFound != NoError;
6936}
6937
6938StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
6939                                            Stmt *AStmt,
6940                                            SourceLocation StartLoc,
6941                                            SourceLocation EndLoc) {
6942  if (!AStmt)
6943    return StmtError();
6944
6945  auto *CS = cast<CapturedStmt>(AStmt);
6946  // 1.2.2 OpenMP Language Terminology
6947  // Structured block - An executable statement with a single entry at the
6948  // top and a single exit at the bottom.
6949  // The point of exit cannot be a branch out of the structured block.
6950  // longjmp() and throw() must not violate the entry/exit criteria.
6951  OpenMPClauseKind AtomicKind = OMPC_unknown;
6952  SourceLocation AtomicKindLoc;
6953  for (const OMPClause *C : Clauses) {
6954    if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
6955        C->getClauseKind() == OMPC_update ||
6956        C->getClauseKind() == OMPC_capture) {
6957      if (AtomicKind != OMPC_unknown) {
6958        Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
6959            << SourceRange(C->getBeginLoc(), C->getEndLoc());
6960        Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6961            << getOpenMPClauseName(AtomicKind);
6962      } else {
6963        AtomicKind = C->getClauseKind();
6964        AtomicKindLoc = C->getBeginLoc();
6965      }
6966    }
6967  }
6968
6969  Stmt *Body = CS->getCapturedStmt();
6970  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6971    Body = EWC->getSubExpr();
6972
6973  Expr *X = nullptr;
6974  Expr *V = nullptr;
6975  Expr *E = nullptr;
6976  Expr *UE = nullptr;
6977  bool IsXLHSInRHSPart = false;
6978  bool IsPostfixUpdate = false;
6979  // OpenMP [2.12.6, atomic Construct]
6980  // In the next expressions:
6981  // * x and v (as applicable) are both l-value expressions with scalar type.
6982  // * During the execution of an atomic region, multiple syntactic
6983  // occurrences of x must designate the same storage location.
6984  // * Neither of v and expr (as applicable) may access the storage location
6985  // designated by x.
6986  // * Neither of x and expr (as applicable) may access the storage location
6987  // designated by v.
6988  // * expr is an expression with scalar type.
6989  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
6990  // * binop, binop=, ++, and -- are not overloaded operators.
6991  // * The expression x binop expr must be numerically equivalent to x binop
6992  // (expr). This requirement is satisfied if the operators in expr have
6993  // precedence greater than binop, or by using parentheses around expr or
6994  // subexpressions of expr.
6995  // * The expression expr binop x must be numerically equivalent to (expr)
6996  // binop x. This requirement is satisfied if the operators in expr have
6997  // precedence equal to or greater than binop, or by using parentheses around
6998  // expr or subexpressions of expr.
6999  // * For forms that allow multiple occurrences of x, the number of times
7000  // that x is evaluated is unspecified.
7001  if (AtomicKind == OMPC_read) {
7002    enum {
7003      NotAnExpression,
7004      NotAnAssignmentOp,
7005      NotAScalarType,
7006      NotAnLValue,
7007      NoError
7008    } ErrorFound = NoError;
7009    SourceLocation ErrorLocNoteLoc;
7010    SourceRange ErrorRangeNoteRange;
7011    // If clause is read:
7012    //  v = x;
7013    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
7014      const auto *AtomicBinOp =
7015          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
7016      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
7017        X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
7018        V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
7019        if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
7020            (V->isInstantiationDependent() || V->getType()->isScalarType())) {
7021          if (!X->isLValue() || !V->isLValue()) {
7022            const Expr *NotLValueExpr = X->isLValue() ? V : X;
7023            ErrorFound = NotAnLValue;
7024            ErrorLoc = AtomicBinOp->getExprLoc();
7025            ErrorRange = AtomicBinOp->getSourceRange();
7026            NoteLoc = NotLValueExpr->getExprLoc();
7027            NoteRange = NotLValueExpr->getSourceRange();
7028          }
7029        } else if (!X->isInstantiationDependent() ||
7030                   !V->isInstantiationDependent()) {
7031          const Expr *NotScalarExpr =
7032              (X->isInstantiationDependent() || X->getType()->isScalarType())
7033                  ? V
7034                  : X;
7035          ErrorFound = NotAScalarType;
7036          ErrorLoc = AtomicBinOp->getExprLoc();
7037          ErrorRange = AtomicBinOp->getSourceRange();
7038          NoteLoc = NotScalarExpr->getExprLoc();
7039          NoteRange = NotScalarExpr->getSourceRange();
7040        }
7041      } else if (!AtomicBody->isInstantiationDependent()) {
7042        ErrorFound = NotAnAssignmentOp;
7043        ErrorLoc = AtomicBody->getExprLoc();
7044        ErrorRange = AtomicBody->getSourceRange();
7045        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
7046                              : AtomicBody->getExprLoc();
7047        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
7048                                : AtomicBody->getSourceRange();
7049      }
7050    } else {
7051      ErrorFound = NotAnExpression;
7052      NoteLoc = ErrorLoc = Body->getBeginLoc();
7053      NoteRange = ErrorRange = SourceRange(NoteLocNoteLoc);
7054    }
7055    if (ErrorFound != NoError) {
7056      Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
7057          << ErrorRange;
7058      Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
7059                                                      << NoteRange;
7060      return StmtError();
7061    }
7062    if (CurContext->isDependentContext())
7063      V = X = nullptr;
7064  } else if (AtomicKind == OMPC_write) {
7065    enum {
7066      NotAnExpression,
7067      NotAnAssignmentOp,
7068      NotAScalarType,
7069      NotAnLValue,
7070      NoError
7071    } ErrorFound = NoError;
7072    SourceLocation ErrorLocNoteLoc;
7073    SourceRange ErrorRangeNoteRange;
7074    // If clause is write:
7075    //  x = expr;
7076    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
7077      const auto *AtomicBinOp =
7078          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
7079      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
7080        X = AtomicBinOp->getLHS();
7081        E = AtomicBinOp->getRHS();
7082        if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
7083            (E->isInstantiationDependent() || E->getType()->isScalarType())) {
7084          if (!X->isLValue()) {
7085            ErrorFound = NotAnLValue;
7086            ErrorLoc = AtomicBinOp->getExprLoc();
7087            ErrorRange = AtomicBinOp->getSourceRange();
7088            NoteLoc = X->getExprLoc();
7089            NoteRange = X->getSourceRange();
7090          }
7091        } else if (!X->isInstantiationDependent() ||
7092                   !E->isInstantiationDependent()) {
7093          const Expr *NotScalarExpr =
7094              (X->isInstantiationDependent() || X->getType()->isScalarType())
7095                  ? E
7096                  : X;
7097          ErrorFound = NotAScalarType;
7098          ErrorLoc = AtomicBinOp->getExprLoc();
7099          ErrorRange = AtomicBinOp->getSourceRange();
7100          NoteLoc = NotScalarExpr->getExprLoc();
7101          NoteRange = NotScalarExpr->getSourceRange();
7102        }
7103      } else if (!AtomicBody->isInstantiationDependent()) {
7104        ErrorFound = NotAnAssignmentOp;
7105        ErrorLoc = AtomicBody->getExprLoc();
7106        ErrorRange = AtomicBody->getSourceRange();
7107        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
7108                              : AtomicBody->getExprLoc();
7109        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
7110                                : AtomicBody->getSourceRange();
7111      }
7112    } else {
7113      ErrorFound = NotAnExpression;
7114      NoteLoc = ErrorLoc = Body->getBeginLoc();
7115      NoteRange = ErrorRange = SourceRange(NoteLocNoteLoc);
7116    }
7117    if (ErrorFound != NoError) {
7118      Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
7119          << ErrorRange;
7120      Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
7121                                                      << NoteRange;
7122      return StmtError();
7123    }
7124    if (CurContext->isDependentContext())
7125      E = X = nullptr;
7126  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
7127    // If clause is update:
7128    //  x++;
7129    //  x--;
7130    //  ++x;
7131    //  --x;
7132    //  x binop= expr;
7133    //  x = x binop expr;
7134    //  x = expr binop x;
7135    OpenMPAtomicUpdateChecker Checker(*this);
7136    if (Checker.checkStatement(
7137            Body, (AtomicKind == OMPC_update)
7138                      ? diag::err_omp_atomic_update_not_expression_statement
7139                      : diag::err_omp_atomic_not_expression_statement,
7140            diag::note_omp_atomic_update))
7141      return StmtError();
7142    if (!CurContext->isDependentContext()) {
7143      E = Checker.getExpr();
7144      X = Checker.getX();
7145      UE = Checker.getUpdateExpr();
7146      IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
7147    }
7148  } else if (AtomicKind == OMPC_capture) {
7149    enum {
7150      NotAnAssignmentOp,
7151      NotACompoundStatement,
7152      NotTwoSubstatements,
7153      NotASpecificExpression,
7154      NoError
7155    } ErrorFound = NoError;
7156    SourceLocation ErrorLocNoteLoc;
7157    SourceRange ErrorRangeNoteRange;
7158    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
7159      // If clause is a capture:
7160      //  v = x++;
7161      //  v = x--;
7162      //  v = ++x;
7163      //  v = --x;
7164      //  v = x binop= expr;
7165      //  v = x = x binop expr;
7166      //  v = x = expr binop x;
7167      const auto *AtomicBinOp =
7168          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
7169      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
7170        V = AtomicBinOp->getLHS();
7171        Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
7172        OpenMPAtomicUpdateChecker Checker(*this);
7173        if (Checker.checkStatement(
7174                Body, diag::err_omp_atomic_capture_not_expression_statement,
7175                diag::note_omp_atomic_update))
7176          return StmtError();
7177        E = Checker.getExpr();
7178        X = Checker.getX();
7179        UE = Checker.getUpdateExpr();
7180        IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
7181        IsPostfixUpdate = Checker.isPostfixUpdate();
7182      } else if (!AtomicBody->isInstantiationDependent()) {
7183        ErrorLoc = AtomicBody->getExprLoc();
7184        ErrorRange = AtomicBody->getSourceRange();
7185        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
7186                              : AtomicBody->getExprLoc();
7187        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
7188                                : AtomicBody->getSourceRange();
7189        ErrorFound = NotAnAssignmentOp;
7190      }
7191      if (ErrorFound != NoError) {
7192        Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
7193            << ErrorRange;
7194        Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
7195        return StmtError();
7196      }
7197      if (CurContext->isDependentContext())
7198        UE = V = E = X = nullptr;
7199    } else {
7200      // If clause is a capture:
7201      //  { v = x; x = expr; }
7202      //  { v = x; x++; }
7203      //  { v = x; x--; }
7204      //  { v = x; ++x; }
7205      //  { v = x; --x; }
7206      //  { v = x; x binop= expr; }
7207      //  { v = x; x = x binop expr; }
7208      //  { v = x; x = expr binop x; }
7209      //  { x++; v = x; }
7210      //  { x--; v = x; }
7211      //  { ++x; v = x; }
7212      //  { --x; v = x; }
7213      //  { x binop= expr; v = x; }
7214      //  { x = x binop expr; v = x; }
7215      //  { x = expr binop x; v = x; }
7216      if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
7217        // Check that this is { expr1; expr2; }
7218        if (CS->size() == 2) {
7219          Stmt *First = CS->body_front();
7220          Stmt *Second = CS->body_back();
7221          if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
7222            First = EWC->getSubExpr()->IgnoreParenImpCasts();
7223          if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
7224            Second = EWC->getSubExpr()->IgnoreParenImpCasts();
7225          // Need to find what subexpression is 'v' and what is 'x'.
7226          OpenMPAtomicUpdateChecker Checker(*this);
7227          bool IsUpdateExprFound = !Checker.checkStatement(Second);
7228          BinaryOperator *BinOp = nullptr;
7229          if (IsUpdateExprFound) {
7230            BinOp = dyn_cast<BinaryOperator>(First);
7231            IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
7232          }
7233          if (IsUpdateExprFound && !CurContext->isDependentContext()) {
7234            //  { v = x; x++; }
7235            //  { v = x; x--; }
7236            //  { v = x; ++x; }
7237            //  { v = x; --x; }
7238            //  { v = x; x binop= expr; }
7239            //  { v = x; x = x binop expr; }
7240            //  { v = x; x = expr binop x; }
7241            // Check that the first expression has form v = x.
7242            Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
7243            llvm::FoldingSetNodeID XIdPossibleXId;
7244            Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
7245            PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
7246            IsUpdateExprFound = XId == PossibleXId;
7247            if (IsUpdateExprFound) {
7248              V = BinOp->getLHS();
7249              X = Checker.getX();
7250              E = Checker.getExpr();
7251              UE = Checker.getUpdateExpr();
7252              IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
7253              IsPostfixUpdate = true;
7254            }
7255          }
7256          if (!IsUpdateExprFound) {
7257            IsUpdateExprFound = !Checker.checkStatement(First);
7258            BinOp = nullptr;
7259            if (IsUpdateExprFound) {
7260              BinOp = dyn_cast<BinaryOperator>(Second);
7261              IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
7262            }
7263            if (IsUpdateExprFound && !CurContext->isDependentContext()) {
7264              //  { x++; v = x; }
7265              //  { x--; v = x; }
7266              //  { ++x; v = x; }
7267              //  { --x; v = x; }
7268              //  { x binop= expr; v = x; }
7269              //  { x = x binop expr; v = x; }
7270              //  { x = expr binop x; v = x; }
7271              // Check that the second expression has form v = x.
7272              Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
7273              llvm::FoldingSetNodeID XIdPossibleXId;
7274              Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
7275              PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
7276              IsUpdateExprFound = XId == PossibleXId;
7277              if (IsUpdateExprFound) {
7278                V = BinOp->getLHS();
7279                X = Checker.getX();
7280                E = Checker.getExpr();
7281                UE = Checker.getUpdateExpr();
7282                IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
7283                IsPostfixUpdate = false;
7284              }
7285            }
7286          }
7287          if (!IsUpdateExprFound) {
7288            //  { v = x; x = expr; }
7289            auto *FirstExpr = dyn_cast<Expr>(First);
7290            auto *SecondExpr = dyn_cast<Expr>(Second);
7291            if (!FirstExpr || !SecondExpr ||
7292                !(FirstExpr->isInstantiationDependent() ||
7293                  SecondExpr->isInstantiationDependent())) {
7294              auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
7295              if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
7296                ErrorFound = NotAnAssignmentOp;
7297                NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
7298                                                : First->getBeginLoc();
7299                NoteRange = ErrorRange = FirstBinOp
7300                                             ? FirstBinOp->getSourceRange()
7301                                             : SourceRange(ErrorLoc, ErrorLoc);
7302              } else {
7303                auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
7304                if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
7305                  ErrorFound = NotAnAssignmentOp;
7306                  NoteLoc = ErrorLoc = SecondBinOp
7307                                           ? SecondBinOp->getOperatorLoc()
7308                                           : Second->getBeginLoc();
7309                  NoteRange = ErrorRange =
7310                      SecondBinOp ? SecondBinOp->getSourceRange()
7311                                  : SourceRange(ErrorLoc, ErrorLoc);
7312                } else {
7313                  Expr *PossibleXRHSInFirst =
7314                      FirstBinOp->getRHS()->IgnoreParenImpCasts();
7315                  Expr *PossibleXLHSInSecond =
7316                      SecondBinOp->getLHS()->IgnoreParenImpCasts();
7317                  llvm::FoldingSetNodeID X1IdX2Id;
7318                  PossibleXRHSInFirst->Profile(X1Id, Context,
7319                                               /*Canonical=*/true);
7320                  PossibleXLHSInSecond->Profile(X2Id, Context,
7321                                                /*Canonical=*/true);
7322                  IsUpdateExprFound = X1Id == X2Id;
7323                  if (IsUpdateExprFound) {
7324                    V = FirstBinOp->getLHS();
7325                    X = SecondBinOp->getLHS();
7326                    E = SecondBinOp->getRHS();
7327                    UE = nullptr;
7328                    IsXLHSInRHSPart = false;
7329                    IsPostfixUpdate = true;
7330                  } else {
7331                    ErrorFound = NotASpecificExpression;
7332                    ErrorLoc = FirstBinOp->getExprLoc();
7333                    ErrorRange = FirstBinOp->getSourceRange();
7334                    NoteLoc = SecondBinOp->getLHS()->getExprLoc();
7335                    NoteRange = SecondBinOp->getRHS()->getSourceRange();
7336                  }
7337                }
7338              }
7339            }
7340          }
7341        } else {
7342          NoteLoc = ErrorLoc = Body->getBeginLoc();
7343          NoteRange = ErrorRange =
7344              SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
7345          ErrorFound = NotTwoSubstatements;
7346        }
7347      } else {
7348        NoteLoc = ErrorLoc = Body->getBeginLoc();
7349        NoteRange = ErrorRange =
7350            SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
7351        ErrorFound = NotACompoundStatement;
7352      }
7353      if (ErrorFound != NoError) {
7354        Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
7355            << ErrorRange;
7356        Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
7357        return StmtError();
7358      }
7359      if (CurContext->isDependentContext())
7360        UE = V = E = X = nullptr;
7361    }
7362  }
7363
7364  setFunctionHasBranchProtectedScope();
7365
7366  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7367                                    X, V, E, UE, IsXLHSInRHSPart,
7368                                    IsPostfixUpdate);
7369}
7370
7371StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
7372                                            Stmt *AStmt,
7373                                            SourceLocation StartLoc,
7374                                            SourceLocation EndLoc) {
7375  if (!AStmt)
7376    return StmtError();
7377
7378  auto *CS = cast<CapturedStmt>(AStmt);
7379  // 1.2.2 OpenMP Language Terminology
7380  // Structured block - An executable statement with a single entry at the
7381  // top and a single exit at the bottom.
7382  // The point of exit cannot be a branch out of the structured block.
7383  // longjmp() and throw() must not violate the entry/exit criteria.
7384  CS->getCapturedDecl()->setNothrow();
7385  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
7386       ThisCaptureLevel > 1; --ThisCaptureLevel) {
7387    CS = cast<CapturedStmt>(CS->getCapturedStmt());
7388    // 1.2.2 OpenMP Language Terminology
7389    // Structured block - An executable statement with a single entry at the
7390    // top and a single exit at the bottom.
7391    // The point of exit cannot be a branch out of the structured block.
7392    // longjmp() and throw() must not violate the entry/exit criteria.
7393    CS->getCapturedDecl()->setNothrow();
7394  }
7395
7396  // OpenMP [2.16, Nesting of Regions]
7397  // If specified, a teams construct must be contained within a target
7398  // construct. That target construct must contain no statements or directives
7399  // outside of the teams construct.
7400  if (DSAStack->hasInnerTeamsRegion()) {
7401    const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
7402    bool OMPTeamsFound = true;
7403    if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
7404      auto I = CS->body_begin();
7405      while (I != CS->body_end()) {
7406        const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
7407        if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
7408            OMPTeamsFound) {
7409
7410          OMPTeamsFound = false;
7411          break;
7412        }
7413        ++I;
7414      }
7415       (0) . __assert_fail ("I != CS->body_end() && \"Not found statement\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7415, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(I != CS->body_end() && "Not found statement");
7416      S = *I;
7417    } else {
7418      const auto *OED = dyn_cast<OMPExecutableDirective>(S);
7419      OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
7420    }
7421    if (!OMPTeamsFound) {
7422      Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
7423      Diag(DSAStack->getInnerTeamsRegionLoc(),
7424           diag::note_omp_nested_teams_construct_here);
7425      Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
7426          << isa<OMPExecutableDirective>(S);
7427      return StmtError();
7428    }
7429  }
7430
7431  setFunctionHasBranchProtectedScope();
7432
7433  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7434}
7435
7436StmtResult
7437Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
7438                                         Stmt *AStmtSourceLocation StartLoc,
7439                                         SourceLocation EndLoc) {
7440  if (!AStmt)
7441    return StmtError();
7442
7443  auto *CS = cast<CapturedStmt>(AStmt);
7444  // 1.2.2 OpenMP Language Terminology
7445  // Structured block - An executable statement with a single entry at the
7446  // top and a single exit at the bottom.
7447  // The point of exit cannot be a branch out of the structured block.
7448  // longjmp() and throw() must not violate the entry/exit criteria.
7449  CS->getCapturedDecl()->setNothrow();
7450  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
7451       ThisCaptureLevel > 1; --ThisCaptureLevel) {
7452    CS = cast<CapturedStmt>(CS->getCapturedStmt());
7453    // 1.2.2 OpenMP Language Terminology
7454    // Structured block - An executable statement with a single entry at the
7455    // top and a single exit at the bottom.
7456    // The point of exit cannot be a branch out of the structured block.
7457    // longjmp() and throw() must not violate the entry/exit criteria.
7458    CS->getCapturedDecl()->setNothrow();
7459  }
7460
7461  setFunctionHasBranchProtectedScope();
7462
7463  return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
7464                                            AStmt);
7465}
7466
7467StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
7468    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
7469    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7470  if (!AStmt)
7471    return StmtError();
7472
7473  auto *CS = cast<CapturedStmt>(AStmt);
7474  // 1.2.2 OpenMP Language Terminology
7475  // Structured block - An executable statement with a single entry at the
7476  // top and a single exit at the bottom.
7477  // The point of exit cannot be a branch out of the structured block.
7478  // longjmp() and throw() must not violate the entry/exit criteria.
7479  CS->getCapturedDecl()->setNothrow();
7480  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7481       ThisCaptureLevel > 1; --ThisCaptureLevel) {
7482    CS = cast<CapturedStmt>(CS->getCapturedStmt());
7483    // 1.2.2 OpenMP Language Terminology
7484    // Structured block - An executable statement with a single entry at the
7485    // top and a single exit at the bottom.
7486    // The point of exit cannot be a branch out of the structured block.
7487    // longjmp() and throw() must not violate the entry/exit criteria.
7488    CS->getCapturedDecl()->setNothrow();
7489  }
7490
7491  OMPLoopDirective::HelperExprs B;
7492  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7493  // define the nested loops number.
7494  unsigned NestedLoopCount =
7495      checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
7496                      getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7497                      VarsWithImplicitDSA, B);
7498  if (NestedLoopCount == 0)
7499    return StmtError();
7500
7501   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7502, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
7502 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7502, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp target parallel for loop exprs were not built");
7503
7504  if (!CurContext->isDependentContext()) {
7505    // Finalize the clauses that need pre-built expressions for CodeGen.
7506    for (OMPClause *C : Clauses) {
7507      if (auto *LC = dyn_cast<OMPLinearClause>(C))
7508        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7509                                     B.NumIterations, *this, CurScope,
7510                                     DSAStack))
7511          return StmtError();
7512    }
7513  }
7514
7515  setFunctionHasBranchProtectedScope();
7516  return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
7517                                               NestedLoopCount, Clauses, AStmt,
7518                                               B, DSAStack->isCancelRegion());
7519}
7520
7521/// Check for existence of a map clause in the list of clauses.
7522static bool hasClauses(ArrayRef<OMPClause *> Clauses,
7523                       const OpenMPClauseKind K) {
7524  return llvm::any_of(
7525      Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
7526}
7527
7528template <typename... Params>
7529static bool hasClauses(ArrayRef<OMPClause *> Clausesconst OpenMPClauseKind K,
7530                       const Params... ClauseTypes) {
7531  return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
7532}
7533
7534StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
7535                                                Stmt *AStmt,
7536                                                SourceLocation StartLoc,
7537                                                SourceLocation EndLoc) {
7538  if (!AStmt)
7539    return StmtError();
7540
7541   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7541, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7542
7543  // OpenMP [2.10.1, Restrictions, p. 97]
7544  // At least one map clause must appear on the directive.
7545  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
7546    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7547        << "'map' or 'use_device_ptr'"
7548        << getOpenMPDirectiveName(OMPD_target_data);
7549    return StmtError();
7550  }
7551
7552  setFunctionHasBranchProtectedScope();
7553
7554  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7555                                        AStmt);
7556}
7557
7558StmtResult
7559Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
7560                                          SourceLocation StartLoc,
7561                                          SourceLocation EndLocStmt *AStmt) {
7562  if (!AStmt)
7563    return StmtError();
7564
7565  auto *CS = cast<CapturedStmt>(AStmt);
7566  // 1.2.2 OpenMP Language Terminology
7567  // Structured block - An executable statement with a single entry at the
7568  // top and a single exit at the bottom.
7569  // The point of exit cannot be a branch out of the structured block.
7570  // longjmp() and throw() must not violate the entry/exit criteria.
7571  CS->getCapturedDecl()->setNothrow();
7572  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
7573       ThisCaptureLevel > 1; --ThisCaptureLevel) {
7574    CS = cast<CapturedStmt>(CS->getCapturedStmt());
7575    // 1.2.2 OpenMP Language Terminology
7576    // Structured block - An executable statement with a single entry at the
7577    // top and a single exit at the bottom.
7578    // The point of exit cannot be a branch out of the structured block.
7579    // longjmp() and throw() must not violate the entry/exit criteria.
7580    CS->getCapturedDecl()->setNothrow();
7581  }
7582
7583  // OpenMP [2.10.2, Restrictions, p. 99]
7584  // At least one map clause must appear on the directive.
7585  if (!hasClauses(Clauses, OMPC_map)) {
7586    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7587        << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
7588    return StmtError();
7589  }
7590
7591  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7592                                             AStmt);
7593}
7594
7595StmtResult
7596Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
7597                                         SourceLocation StartLoc,
7598                                         SourceLocation EndLocStmt *AStmt) {
7599  if (!AStmt)
7600    return StmtError();
7601
7602  auto *CS = cast<CapturedStmt>(AStmt);
7603  // 1.2.2 OpenMP Language Terminology
7604  // Structured block - An executable statement with a single entry at the
7605  // top and a single exit at the bottom.
7606  // The point of exit cannot be a branch out of the structured block.
7607  // longjmp() and throw() must not violate the entry/exit criteria.
7608  CS->getCapturedDecl()->setNothrow();
7609  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
7610       ThisCaptureLevel > 1; --ThisCaptureLevel) {
7611    CS = cast<CapturedStmt>(CS->getCapturedStmt());
7612    // 1.2.2 OpenMP Language Terminology
7613    // Structured block - An executable statement with a single entry at the
7614    // top and a single exit at the bottom.
7615    // The point of exit cannot be a branch out of the structured block.
7616    // longjmp() and throw() must not violate the entry/exit criteria.
7617    CS->getCapturedDecl()->setNothrow();
7618  }
7619
7620  // OpenMP [2.10.3, Restrictions, p. 102]
7621  // At least one map clause must appear on the directive.
7622  if (!hasClauses(Clauses, OMPC_map)) {
7623    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7624        << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
7625    return StmtError();
7626  }
7627
7628  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7629                                            AStmt);
7630}
7631
7632StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
7633                                                  SourceLocation StartLoc,
7634                                                  SourceLocation EndLoc,
7635                                                  Stmt *AStmt) {
7636  if (!AStmt)
7637    return StmtError();
7638
7639  auto *CS = cast<CapturedStmt>(AStmt);
7640  // 1.2.2 OpenMP Language Terminology
7641  // Structured block - An executable statement with a single entry at the
7642  // top and a single exit at the bottom.
7643  // The point of exit cannot be a branch out of the structured block.
7644  // longjmp() and throw() must not violate the entry/exit criteria.
7645  CS->getCapturedDecl()->setNothrow();
7646  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
7647       ThisCaptureLevel > 1; --ThisCaptureLevel) {
7648    CS = cast<CapturedStmt>(CS->getCapturedStmt());
7649    // 1.2.2 OpenMP Language Terminology
7650    // Structured block - An executable statement with a single entry at the
7651    // top and a single exit at the bottom.
7652    // The point of exit cannot be a branch out of the structured block.
7653    // longjmp() and throw() must not violate the entry/exit criteria.
7654    CS->getCapturedDecl()->setNothrow();
7655  }
7656
7657  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
7658    Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
7659    return StmtError();
7660  }
7661  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
7662                                          AStmt);
7663}
7664
7665StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
7666                                           Stmt *AStmtSourceLocation StartLoc,
7667                                           SourceLocation EndLoc) {
7668  if (!AStmt)
7669    return StmtError();
7670
7671  auto *CS = cast<CapturedStmt>(AStmt);
7672  // 1.2.2 OpenMP Language Terminology
7673  // Structured block - An executable statement with a single entry at the
7674  // top and a single exit at the bottom.
7675  // The point of exit cannot be a branch out of the structured block.
7676  // longjmp() and throw() must not violate the entry/exit criteria.
7677  CS->getCapturedDecl()->setNothrow();
7678
7679  setFunctionHasBranchProtectedScope();
7680
7681  DSAStack->setParentTeamsRegionLoc(StartLoc);
7682
7683  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7684}
7685
7686StmtResult
7687Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
7688                                            SourceLocation EndLoc,
7689                                            OpenMPDirectiveKind CancelRegion) {
7690  if (DSAStack->isParentNowaitRegion()) {
7691    Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
7692    return StmtError();
7693  }
7694  if (DSAStack->isParentOrderedRegion()) {
7695    Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
7696    return StmtError();
7697  }
7698  return OMPCancellationPointDirective::Create(ContextStartLocEndLoc,
7699                                               CancelRegion);
7700}
7701
7702StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
7703                                            SourceLocation StartLoc,
7704                                            SourceLocation EndLoc,
7705                                            OpenMPDirectiveKind CancelRegion) {
7706  if (DSAStack->isParentNowaitRegion()) {
7707    Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
7708    return StmtError();
7709  }
7710  if (DSAStack->isParentOrderedRegion()) {
7711    Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
7712    return StmtError();
7713  }
7714  DSAStack->setParentCancelRegion(/*Cancel=*/true);
7715  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
7716                                    CancelRegion);
7717}
7718
7719static bool checkGrainsizeNumTasksClauses(Sema &S,
7720                                          ArrayRef<OMPClause *> Clauses) {
7721  const OMPClause *PrevClause = nullptr;
7722  bool ErrorFound = false;
7723  for (const OMPClause *C : Clauses) {
7724    if (C->getClauseKind() == OMPC_grainsize ||
7725        C->getClauseKind() == OMPC_num_tasks) {
7726      if (!PrevClause)
7727        PrevClause = C;
7728      else if (PrevClause->getClauseKind() != C->getClauseKind()) {
7729        S.Diag(C->getBeginLoc(),
7730               diag::err_omp_grainsize_num_tasks_mutually_exclusive)
7731            << getOpenMPClauseName(C->getClauseKind())
7732            << getOpenMPClauseName(PrevClause->getClauseKind());
7733        S.Diag(PrevClause->getBeginLoc(),
7734               diag::note_omp_previous_grainsize_num_tasks)
7735            << getOpenMPClauseName(PrevClause->getClauseKind());
7736        ErrorFound = true;
7737      }
7738    }
7739  }
7740  return ErrorFound;
7741}
7742
7743static bool checkReductionClauseWithNogroup(Sema &S,
7744                                            ArrayRef<OMPClause *> Clauses) {
7745  const OMPClause *ReductionClause = nullptr;
7746  const OMPClause *NogroupClause = nullptr;
7747  for (const OMPClause *C : Clauses) {
7748    if (C->getClauseKind() == OMPC_reduction) {
7749      ReductionClause = C;
7750      if (NogroupClause)
7751        break;
7752      continue;
7753    }
7754    if (C->getClauseKind() == OMPC_nogroup) {
7755      NogroupClause = C;
7756      if (ReductionClause)
7757        break;
7758      continue;
7759    }
7760  }
7761  if (ReductionClause && NogroupClause) {
7762    S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
7763        << SourceRange(NogroupClause->getBeginLoc(),
7764                       NogroupClause->getEndLoc());
7765    return true;
7766  }
7767  return false;
7768}
7769
7770StmtResult Sema::ActOnOpenMPTaskLoopDirective(
7771    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
7772    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7773  if (!AStmt)
7774    return StmtError();
7775
7776   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7776, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7777  OMPLoopDirective::HelperExprs B;
7778  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7779  // define the nested loops number.
7780  unsigned NestedLoopCount =
7781      checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
7782                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7783                      VarsWithImplicitDSA, B);
7784  if (NestedLoopCount == 0)
7785    return StmtError();
7786
7787   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7788, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
7788 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7788, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for loop exprs were not built");
7789
7790  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7791  // The grainsize clause and num_tasks clause are mutually exclusive and may
7792  // not appear on the same taskloop directive.
7793  if (checkGrainsizeNumTasksClauses(*this, Clauses))
7794    return StmtError();
7795  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7796  // If a reduction clause is present on the taskloop directive, the nogroup
7797  // clause must not be specified.
7798  if (checkReductionClauseWithNogroup(*this, Clauses))
7799    return StmtError();
7800
7801  setFunctionHasBranchProtectedScope();
7802  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
7803                                      NestedLoopCount, Clauses, AStmt, B);
7804}
7805
7806StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
7807    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
7808    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7809  if (!AStmt)
7810    return StmtError();
7811
7812   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7812, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7813  OMPLoopDirective::HelperExprs B;
7814  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7815  // define the nested loops number.
7816  unsigned NestedLoopCount =
7817      checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
7818                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7819                      VarsWithImplicitDSA, B);
7820  if (NestedLoopCount == 0)
7821    return StmtError();
7822
7823   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7824, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
7824 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7824, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for loop exprs were not built");
7825
7826  if (!CurContext->isDependentContext()) {
7827    // Finalize the clauses that need pre-built expressions for CodeGen.
7828    for (OMPClause *C : Clauses) {
7829      if (auto *LC = dyn_cast<OMPLinearClause>(C))
7830        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7831                                     B.NumIterations, *this, CurScope,
7832                                     DSAStack))
7833          return StmtError();
7834    }
7835  }
7836
7837  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7838  // The grainsize clause and num_tasks clause are mutually exclusive and may
7839  // not appear on the same taskloop directive.
7840  if (checkGrainsizeNumTasksClauses(*this, Clauses))
7841    return StmtError();
7842  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7843  // If a reduction clause is present on the taskloop directive, the nogroup
7844  // clause must not be specified.
7845  if (checkReductionClauseWithNogroup(*this, Clauses))
7846    return StmtError();
7847  if (checkSimdlenSafelenSpecified(*this, Clauses))
7848    return StmtError();
7849
7850  setFunctionHasBranchProtectedScope();
7851  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
7852                                          NestedLoopCount, Clauses, AStmt, B);
7853}
7854
7855StmtResult Sema::ActOnOpenMPDistributeDirective(
7856    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
7857    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7858  if (!AStmt)
7859    return StmtError();
7860
7861   (0) . __assert_fail ("isa(AStmt) && \"Captured statement expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7861, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7862  OMPLoopDirective::HelperExprs B;
7863  // In presence of clause 'collapse' with number of loops, it will
7864  // define the nested loops number.
7865  unsigned NestedLoopCount =
7866      checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
7867                      nullptr /*ordered not a clause on distribute*/, AStmt,
7868                      *this, *DSAStack, VarsWithImplicitDSA, B);
7869  if (NestedLoopCount == 0)
7870    return StmtError();
7871
7872   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7873, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
7873 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7873, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for loop exprs were not built");
7874
7875  setFunctionHasBranchProtectedScope();
7876  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
7877                                        NestedLoopCount, Clauses, AStmt, B);
7878}
7879
7880StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
7881    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
7882    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7883  if (!AStmt)
7884    return StmtError();
7885
7886  auto *CS = cast<CapturedStmt>(AStmt);
7887  // 1.2.2 OpenMP Language Terminology
7888  // Structured block - An executable statement with a single entry at the
7889  // top and a single exit at the bottom.
7890  // The point of exit cannot be a branch out of the structured block.
7891  // longjmp() and throw() must not violate the entry/exit criteria.
7892  CS->getCapturedDecl()->setNothrow();
7893  for (int ThisCaptureLevel =
7894           getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
7895       ThisCaptureLevel > 1; --ThisCaptureLevel) {
7896    CS = cast<CapturedStmt>(CS->getCapturedStmt());
7897    // 1.2.2 OpenMP Language Terminology
7898    // Structured block - An executable statement with a single entry at the
7899    // top and a single exit at the bottom.
7900    // The point of exit cannot be a branch out of the structured block.
7901    // longjmp() and throw() must not violate the entry/exit criteria.
7902    CS->getCapturedDecl()->setNothrow();
7903  }
7904
7905  OMPLoopDirective::HelperExprs B;
7906  // In presence of clause 'collapse' with number of loops, it will
7907  // define the nested loops number.
7908  unsigned NestedLoopCount = checkOpenMPLoop(
7909      OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7910      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7911      VarsWithImplicitDSA, B);
7912  if (NestedLoopCount == 0)
7913    return StmtError();
7914
7915   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7916, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
7916 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7916, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for loop exprs were not built");
7917
7918  setFunctionHasBranchProtectedScope();
7919  return OMPDistributeParallelForDirective::Create(
7920      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7921      DSAStack->isCancelRegion());
7922}
7923
7924StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
7925    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
7926    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7927  if (!AStmt)
7928    return StmtError();
7929
7930  auto *CS = cast<CapturedStmt>(AStmt);
7931  // 1.2.2 OpenMP Language Terminology
7932  // Structured block - An executable statement with a single entry at the
7933  // top and a single exit at the bottom.
7934  // The point of exit cannot be a branch out of the structured block.
7935  // longjmp() and throw() must not violate the entry/exit criteria.
7936  CS->getCapturedDecl()->setNothrow();
7937  for (int ThisCaptureLevel =
7938           getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
7939       ThisCaptureLevel > 1; --ThisCaptureLevel) {
7940    CS = cast<CapturedStmt>(CS->getCapturedStmt());
7941    // 1.2.2 OpenMP Language Terminology
7942    // Structured block - An executable statement with a single entry at the
7943    // top and a single exit at the bottom.
7944    // The point of exit cannot be a branch out of the structured block.
7945    // longjmp() and throw() must not violate the entry/exit criteria.
7946    CS->getCapturedDecl()->setNothrow();
7947  }
7948
7949  OMPLoopDirective::HelperExprs B;
7950  // In presence of clause 'collapse' with number of loops, it will
7951  // define the nested loops number.
7952  unsigned NestedLoopCount = checkOpenMPLoop(
7953      OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7954      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7955      VarsWithImplicitDSA, B);
7956  if (NestedLoopCount == 0)
7957    return StmtError();
7958
7959   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7960, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
7960 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 7960, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for loop exprs were not built");
7961
7962  if (!CurContext->isDependentContext()) {
7963    // Finalize the clauses that need pre-built expressions for CodeGen.
7964    for (OMPClause *C : Clauses) {
7965      if (auto *LC = dyn_cast<OMPLinearClause>(C))
7966        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7967                                     B.NumIterations, *this, CurScope,
7968                                     DSAStack))
7969          return StmtError();
7970    }
7971  }
7972
7973  if (checkSimdlenSafelenSpecified(*this, Clauses))
7974    return StmtError();
7975
7976  setFunctionHasBranchProtectedScope();
7977  return OMPDistributeParallelForSimdDirective::Create(
7978      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7979}
7980
7981StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
7982    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
7983    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7984  if (!AStmt)
7985    return StmtError();
7986
7987  auto *CS = cast<CapturedStmt>(AStmt);
7988  // 1.2.2 OpenMP Language Terminology
7989  // Structured block - An executable statement with a single entry at the
7990  // top and a single exit at the bottom.
7991  // The point of exit cannot be a branch out of the structured block.
7992  // longjmp() and throw() must not violate the entry/exit criteria.
7993  CS->getCapturedDecl()->setNothrow();
7994  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7995       ThisCaptureLevel > 1; --ThisCaptureLevel) {
7996    CS = cast<CapturedStmt>(CS->getCapturedStmt());
7997    // 1.2.2 OpenMP Language Terminology
7998    // Structured block - An executable statement with a single entry at the
7999    // top and a single exit at the bottom.
8000    // The point of exit cannot be a branch out of the structured block.
8001    // longjmp() and throw() must not violate the entry/exit criteria.
8002    CS->getCapturedDecl()->setNothrow();
8003  }
8004
8005  OMPLoopDirective::HelperExprs B;
8006  // In presence of clause 'collapse' with number of loops, it will
8007  // define the nested loops number.
8008  unsigned NestedLoopCount =
8009      checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
8010                      nullptr /*ordered not a clause on distribute*/, CS, *this,
8011                      *DSAStack, VarsWithImplicitDSA, B);
8012  if (NestedLoopCount == 0)
8013    return StmtError();
8014
8015   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8016, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8016 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8016, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for loop exprs were not built");
8017
8018  if (!CurContext->isDependentContext()) {
8019    // Finalize the clauses that need pre-built expressions for CodeGen.
8020    for (OMPClause *C : Clauses) {
8021      if (auto *LC = dyn_cast<OMPLinearClause>(C))
8022        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8023                                     B.NumIterations, *this, CurScope,
8024                                     DSAStack))
8025          return StmtError();
8026    }
8027  }
8028
8029  if (checkSimdlenSafelenSpecified(*this, Clauses))
8030    return StmtError();
8031
8032  setFunctionHasBranchProtectedScope();
8033  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
8034                                            NestedLoopCount, Clauses, AStmt, B);
8035}
8036
8037StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
8038    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8039    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8040  if (!AStmt)
8041    return StmtError();
8042
8043  auto *CS = cast<CapturedStmt>(AStmt);
8044  // 1.2.2 OpenMP Language Terminology
8045  // Structured block - An executable statement with a single entry at the
8046  // top and a single exit at the bottom.
8047  // The point of exit cannot be a branch out of the structured block.
8048  // longjmp() and throw() must not violate the entry/exit criteria.
8049  CS->getCapturedDecl()->setNothrow();
8050  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
8051       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8052    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8053    // 1.2.2 OpenMP Language Terminology
8054    // Structured block - An executable statement with a single entry at the
8055    // top and a single exit at the bottom.
8056    // The point of exit cannot be a branch out of the structured block.
8057    // longjmp() and throw() must not violate the entry/exit criteria.
8058    CS->getCapturedDecl()->setNothrow();
8059  }
8060
8061  OMPLoopDirective::HelperExprs B;
8062  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8063  // define the nested loops number.
8064  unsigned NestedLoopCount = checkOpenMPLoop(
8065      OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
8066      getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
8067      VarsWithImplicitDSA, B);
8068  if (NestedLoopCount == 0)
8069    return StmtError();
8070
8071   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8072, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8072 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8072, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp target parallel for simd loop exprs were not built");
8073
8074  if (!CurContext->isDependentContext()) {
8075    // Finalize the clauses that need pre-built expressions for CodeGen.
8076    for (OMPClause *C : Clauses) {
8077      if (auto *LC = dyn_cast<OMPLinearClause>(C))
8078        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8079                                     B.NumIterations, *this, CurScope,
8080                                     DSAStack))
8081          return StmtError();
8082    }
8083  }
8084  if (checkSimdlenSafelenSpecified(*this, Clauses))
8085    return StmtError();
8086
8087  setFunctionHasBranchProtectedScope();
8088  return OMPTargetParallelForSimdDirective::Create(
8089      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8090}
8091
8092StmtResult Sema::ActOnOpenMPTargetSimdDirective(
8093    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8094    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8095  if (!AStmt)
8096    return StmtError();
8097
8098  auto *CS = cast<CapturedStmt>(AStmt);
8099  // 1.2.2 OpenMP Language Terminology
8100  // Structured block - An executable statement with a single entry at the
8101  // top and a single exit at the bottom.
8102  // The point of exit cannot be a branch out of the structured block.
8103  // longjmp() and throw() must not violate the entry/exit criteria.
8104  CS->getCapturedDecl()->setNothrow();
8105  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
8106       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8107    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8108    // 1.2.2 OpenMP Language Terminology
8109    // Structured block - An executable statement with a single entry at the
8110    // top and a single exit at the bottom.
8111    // The point of exit cannot be a branch out of the structured block.
8112    // longjmp() and throw() must not violate the entry/exit criteria.
8113    CS->getCapturedDecl()->setNothrow();
8114  }
8115
8116  OMPLoopDirective::HelperExprs B;
8117  // In presence of clause 'collapse' with number of loops, it will define the
8118  // nested loops number.
8119  unsigned NestedLoopCount =
8120      checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
8121                      getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
8122                      VarsWithImplicitDSA, B);
8123  if (NestedLoopCount == 0)
8124    return StmtError();
8125
8126   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8127, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8127 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8127, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp target simd loop exprs were not built");
8128
8129  if (!CurContext->isDependentContext()) {
8130    // Finalize the clauses that need pre-built expressions for CodeGen.
8131    for (OMPClause *C : Clauses) {
8132      if (auto *LC = dyn_cast<OMPLinearClause>(C))
8133        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8134                                     B.NumIterations, *this, CurScope,
8135                                     DSAStack))
8136          return StmtError();
8137    }
8138  }
8139
8140  if (checkSimdlenSafelenSpecified(*this, Clauses))
8141    return StmtError();
8142
8143  setFunctionHasBranchProtectedScope();
8144  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
8145                                        NestedLoopCount, Clauses, AStmt, B);
8146}
8147
8148StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
8149    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8150    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8151  if (!AStmt)
8152    return StmtError();
8153
8154  auto *CS = cast<CapturedStmt>(AStmt);
8155  // 1.2.2 OpenMP Language Terminology
8156  // Structured block - An executable statement with a single entry at the
8157  // top and a single exit at the bottom.
8158  // The point of exit cannot be a branch out of the structured block.
8159  // longjmp() and throw() must not violate the entry/exit criteria.
8160  CS->getCapturedDecl()->setNothrow();
8161  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
8162       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8163    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8164    // 1.2.2 OpenMP Language Terminology
8165    // Structured block - An executable statement with a single entry at the
8166    // top and a single exit at the bottom.
8167    // The point of exit cannot be a branch out of the structured block.
8168    // longjmp() and throw() must not violate the entry/exit criteria.
8169    CS->getCapturedDecl()->setNothrow();
8170  }
8171
8172  OMPLoopDirective::HelperExprs B;
8173  // In presence of clause 'collapse' with number of loops, it will
8174  // define the nested loops number.
8175  unsigned NestedLoopCount =
8176      checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
8177                      nullptr /*ordered not a clause on distribute*/, CS, *this,
8178                      *DSAStack, VarsWithImplicitDSA, B);
8179  if (NestedLoopCount == 0)
8180    return StmtError();
8181
8182   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8183, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8183 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8183, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp teams distribute loop exprs were not built");
8184
8185  setFunctionHasBranchProtectedScope();
8186
8187  DSAStack->setParentTeamsRegionLoc(StartLoc);
8188
8189  return OMPTeamsDistributeDirective::Create(
8190      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8191}
8192
8193StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
8194    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8195    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8196  if (!AStmt)
8197    return StmtError();
8198
8199  auto *CS = cast<CapturedStmt>(AStmt);
8200  // 1.2.2 OpenMP Language Terminology
8201  // Structured block - An executable statement with a single entry at the
8202  // top and a single exit at the bottom.
8203  // The point of exit cannot be a branch out of the structured block.
8204  // longjmp() and throw() must not violate the entry/exit criteria.
8205  CS->getCapturedDecl()->setNothrow();
8206  for (int ThisCaptureLevel =
8207           getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
8208       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8209    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8210    // 1.2.2 OpenMP Language Terminology
8211    // Structured block - An executable statement with a single entry at the
8212    // top and a single exit at the bottom.
8213    // The point of exit cannot be a branch out of the structured block.
8214    // longjmp() and throw() must not violate the entry/exit criteria.
8215    CS->getCapturedDecl()->setNothrow();
8216  }
8217
8218
8219  OMPLoopDirective::HelperExprs B;
8220  // In presence of clause 'collapse' with number of loops, it will
8221  // define the nested loops number.
8222  unsigned NestedLoopCount = checkOpenMPLoop(
8223      OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
8224      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8225      VarsWithImplicitDSA, B);
8226
8227  if (NestedLoopCount == 0)
8228    return StmtError();
8229
8230   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8231, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8231 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8231, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp teams distribute simd loop exprs were not built");
8232
8233  if (!CurContext->isDependentContext()) {
8234    // Finalize the clauses that need pre-built expressions for CodeGen.
8235    for (OMPClause *C : Clauses) {
8236      if (auto *LC = dyn_cast<OMPLinearClause>(C))
8237        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8238                                     B.NumIterations, *this, CurScope,
8239                                     DSAStack))
8240          return StmtError();
8241    }
8242  }
8243
8244  if (checkSimdlenSafelenSpecified(*this, Clauses))
8245    return StmtError();
8246
8247  setFunctionHasBranchProtectedScope();
8248
8249  DSAStack->setParentTeamsRegionLoc(StartLoc);
8250
8251  return OMPTeamsDistributeSimdDirective::Create(
8252      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8253}
8254
8255StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
8256    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8257    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8258  if (!AStmt)
8259    return StmtError();
8260
8261  auto *CS = cast<CapturedStmt>(AStmt);
8262  // 1.2.2 OpenMP Language Terminology
8263  // Structured block - An executable statement with a single entry at the
8264  // top and a single exit at the bottom.
8265  // The point of exit cannot be a branch out of the structured block.
8266  // longjmp() and throw() must not violate the entry/exit criteria.
8267  CS->getCapturedDecl()->setNothrow();
8268
8269  for (int ThisCaptureLevel =
8270           getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
8271       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8272    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8273    // 1.2.2 OpenMP Language Terminology
8274    // Structured block - An executable statement with a single entry at the
8275    // top and a single exit at the bottom.
8276    // The point of exit cannot be a branch out of the structured block.
8277    // longjmp() and throw() must not violate the entry/exit criteria.
8278    CS->getCapturedDecl()->setNothrow();
8279  }
8280
8281  OMPLoopDirective::HelperExprs B;
8282  // In presence of clause 'collapse' with number of loops, it will
8283  // define the nested loops number.
8284  unsigned NestedLoopCount = checkOpenMPLoop(
8285      OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
8286      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8287      VarsWithImplicitDSA, B);
8288
8289  if (NestedLoopCount == 0)
8290    return StmtError();
8291
8292   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8293, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8293 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8293, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for loop exprs were not built");
8294
8295  if (!CurContext->isDependentContext()) {
8296    // Finalize the clauses that need pre-built expressions for CodeGen.
8297    for (OMPClause *C : Clauses) {
8298      if (auto *LC = dyn_cast<OMPLinearClause>(C))
8299        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8300                                     B.NumIterations, *this, CurScope,
8301                                     DSAStack))
8302          return StmtError();
8303    }
8304  }
8305
8306  if (checkSimdlenSafelenSpecified(*this, Clauses))
8307    return StmtError();
8308
8309  setFunctionHasBranchProtectedScope();
8310
8311  DSAStack->setParentTeamsRegionLoc(StartLoc);
8312
8313  return OMPTeamsDistributeParallelForSimdDirective::Create(
8314      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8315}
8316
8317StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
8318    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8319    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8320  if (!AStmt)
8321    return StmtError();
8322
8323  auto *CS = cast<CapturedStmt>(AStmt);
8324  // 1.2.2 OpenMP Language Terminology
8325  // Structured block - An executable statement with a single entry at the
8326  // top and a single exit at the bottom.
8327  // The point of exit cannot be a branch out of the structured block.
8328  // longjmp() and throw() must not violate the entry/exit criteria.
8329  CS->getCapturedDecl()->setNothrow();
8330
8331  for (int ThisCaptureLevel =
8332           getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
8333       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8334    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8335    // 1.2.2 OpenMP Language Terminology
8336    // Structured block - An executable statement with a single entry at the
8337    // top and a single exit at the bottom.
8338    // The point of exit cannot be a branch out of the structured block.
8339    // longjmp() and throw() must not violate the entry/exit criteria.
8340    CS->getCapturedDecl()->setNothrow();
8341  }
8342
8343  OMPLoopDirective::HelperExprs B;
8344  // In presence of clause 'collapse' with number of loops, it will
8345  // define the nested loops number.
8346  unsigned NestedLoopCount = checkOpenMPLoop(
8347      OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
8348      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8349      VarsWithImplicitDSA, B);
8350
8351  if (NestedLoopCount == 0)
8352    return StmtError();
8353
8354   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8355, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8355 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8355, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp for loop exprs were not built");
8356
8357  setFunctionHasBranchProtectedScope();
8358
8359  DSAStack->setParentTeamsRegionLoc(StartLoc);
8360
8361  return OMPTeamsDistributeParallelForDirective::Create(
8362      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8363      DSAStack->isCancelRegion());
8364}
8365
8366StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
8367                                                 Stmt *AStmt,
8368                                                 SourceLocation StartLoc,
8369                                                 SourceLocation EndLoc) {
8370  if (!AStmt)
8371    return StmtError();
8372
8373  auto *CS = cast<CapturedStmt>(AStmt);
8374  // 1.2.2 OpenMP Language Terminology
8375  // Structured block - An executable statement with a single entry at the
8376  // top and a single exit at the bottom.
8377  // The point of exit cannot be a branch out of the structured block.
8378  // longjmp() and throw() must not violate the entry/exit criteria.
8379  CS->getCapturedDecl()->setNothrow();
8380
8381  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
8382       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8383    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8384    // 1.2.2 OpenMP Language Terminology
8385    // Structured block - An executable statement with a single entry at the
8386    // top and a single exit at the bottom.
8387    // The point of exit cannot be a branch out of the structured block.
8388    // longjmp() and throw() must not violate the entry/exit criteria.
8389    CS->getCapturedDecl()->setNothrow();
8390  }
8391  setFunctionHasBranchProtectedScope();
8392
8393  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
8394                                         AStmt);
8395}
8396
8397StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
8398    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8399    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8400  if (!AStmt)
8401    return StmtError();
8402
8403  auto *CS = cast<CapturedStmt>(AStmt);
8404  // 1.2.2 OpenMP Language Terminology
8405  // Structured block - An executable statement with a single entry at the
8406  // top and a single exit at the bottom.
8407  // The point of exit cannot be a branch out of the structured block.
8408  // longjmp() and throw() must not violate the entry/exit criteria.
8409  CS->getCapturedDecl()->setNothrow();
8410  for (int ThisCaptureLevel =
8411           getOpenMPCaptureLevels(OMPD_target_teams_distribute);
8412       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8413    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8414    // 1.2.2 OpenMP Language Terminology
8415    // Structured block - An executable statement with a single entry at the
8416    // top and a single exit at the bottom.
8417    // The point of exit cannot be a branch out of the structured block.
8418    // longjmp() and throw() must not violate the entry/exit criteria.
8419    CS->getCapturedDecl()->setNothrow();
8420  }
8421
8422  OMPLoopDirective::HelperExprs B;
8423  // In presence of clause 'collapse' with number of loops, it will
8424  // define the nested loops number.
8425  unsigned NestedLoopCount = checkOpenMPLoop(
8426      OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
8427      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8428      VarsWithImplicitDSA, B);
8429  if (NestedLoopCount == 0)
8430    return StmtError();
8431
8432   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8433, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8433 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8433, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp target teams distribute loop exprs were not built");
8434
8435  setFunctionHasBranchProtectedScope();
8436  return OMPTargetTeamsDistributeDirective::Create(
8437      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8438}
8439
8440StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
8441    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8442    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8443  if (!AStmt)
8444    return StmtError();
8445
8446  auto *CS = cast<CapturedStmt>(AStmt);
8447  // 1.2.2 OpenMP Language Terminology
8448  // Structured block - An executable statement with a single entry at the
8449  // top and a single exit at the bottom.
8450  // The point of exit cannot be a branch out of the structured block.
8451  // longjmp() and throw() must not violate the entry/exit criteria.
8452  CS->getCapturedDecl()->setNothrow();
8453  for (int ThisCaptureLevel =
8454           getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
8455       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8456    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8457    // 1.2.2 OpenMP Language Terminology
8458    // Structured block - An executable statement with a single entry at the
8459    // top and a single exit at the bottom.
8460    // The point of exit cannot be a branch out of the structured block.
8461    // longjmp() and throw() must not violate the entry/exit criteria.
8462    CS->getCapturedDecl()->setNothrow();
8463  }
8464
8465  OMPLoopDirective::HelperExprs B;
8466  // In presence of clause 'collapse' with number of loops, it will
8467  // define the nested loops number.
8468  unsigned NestedLoopCount = checkOpenMPLoop(
8469      OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
8470      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8471      VarsWithImplicitDSA, B);
8472  if (NestedLoopCount == 0)
8473    return StmtError();
8474
8475   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8476, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8476 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8476, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp target teams distribute parallel for loop exprs were not built");
8477
8478  if (!CurContext->isDependentContext()) {
8479    // Finalize the clauses that need pre-built expressions for CodeGen.
8480    for (OMPClause *C : Clauses) {
8481      if (auto *LC = dyn_cast<OMPLinearClause>(C))
8482        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8483                                     B.NumIterations, *this, CurScope,
8484                                     DSAStack))
8485          return StmtError();
8486    }
8487  }
8488
8489  setFunctionHasBranchProtectedScope();
8490  return OMPTargetTeamsDistributeParallelForDirective::Create(
8491      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8492      DSAStack->isCancelRegion());
8493}
8494
8495StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
8496    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8497    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8498  if (!AStmt)
8499    return StmtError();
8500
8501  auto *CS = cast<CapturedStmt>(AStmt);
8502  // 1.2.2 OpenMP Language Terminology
8503  // Structured block - An executable statement with a single entry at the
8504  // top and a single exit at the bottom.
8505  // The point of exit cannot be a branch out of the structured block.
8506  // longjmp() and throw() must not violate the entry/exit criteria.
8507  CS->getCapturedDecl()->setNothrow();
8508  for (int ThisCaptureLevel = getOpenMPCaptureLevels(
8509           OMPD_target_teams_distribute_parallel_for_simd);
8510       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8511    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8512    // 1.2.2 OpenMP Language Terminology
8513    // Structured block - An executable statement with a single entry at the
8514    // top and a single exit at the bottom.
8515    // The point of exit cannot be a branch out of the structured block.
8516    // longjmp() and throw() must not violate the entry/exit criteria.
8517    CS->getCapturedDecl()->setNothrow();
8518  }
8519
8520  OMPLoopDirective::HelperExprs B;
8521  // In presence of clause 'collapse' with number of loops, it will
8522  // define the nested loops number.
8523  unsigned NestedLoopCount =
8524      checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
8525                      getCollapseNumberExpr(Clauses),
8526                      nullptr /*ordered not a clause on distribute*/, CS, *this,
8527                      *DSAStack, VarsWithImplicitDSA, B);
8528  if (NestedLoopCount == 0)
8529    return StmtError();
8530
8531   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8533, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8532 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8533, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp target teams distribute parallel for simd loop exprs were not "
8533 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8533, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "built");
8534
8535  if (!CurContext->isDependentContext()) {
8536    // Finalize the clauses that need pre-built expressions for CodeGen.
8537    for (OMPClause *C : Clauses) {
8538      if (auto *LC = dyn_cast<OMPLinearClause>(C))
8539        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8540                                     B.NumIterations, *this, CurScope,
8541                                     DSAStack))
8542          return StmtError();
8543    }
8544  }
8545
8546  if (checkSimdlenSafelenSpecified(*this, Clauses))
8547    return StmtError();
8548
8549  setFunctionHasBranchProtectedScope();
8550  return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
8551      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8552}
8553
8554StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
8555    ArrayRef<OMPClause *> ClausesStmt *AStmtSourceLocation StartLoc,
8556    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8557  if (!AStmt)
8558    return StmtError();
8559
8560  auto *CS = cast<CapturedStmt>(AStmt);
8561  // 1.2.2 OpenMP Language Terminology
8562  // Structured block - An executable statement with a single entry at the
8563  // top and a single exit at the bottom.
8564  // The point of exit cannot be a branch out of the structured block.
8565  // longjmp() and throw() must not violate the entry/exit criteria.
8566  CS->getCapturedDecl()->setNothrow();
8567  for (int ThisCaptureLevel =
8568           getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
8569       ThisCaptureLevel > 1; --ThisCaptureLevel) {
8570    CS = cast<CapturedStmt>(CS->getCapturedStmt());
8571    // 1.2.2 OpenMP Language Terminology
8572    // Structured block - An executable statement with a single entry at the
8573    // top and a single exit at the bottom.
8574    // The point of exit cannot be a branch out of the structured block.
8575    // longjmp() and throw() must not violate the entry/exit criteria.
8576    CS->getCapturedDecl()->setNothrow();
8577  }
8578
8579  OMPLoopDirective::HelperExprs B;
8580  // In presence of clause 'collapse' with number of loops, it will
8581  // define the nested loops number.
8582  unsigned NestedLoopCount = checkOpenMPLoop(
8583      OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
8584      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8585      VarsWithImplicitDSA, B);
8586  if (NestedLoopCount == 0)
8587    return StmtError();
8588
8589   (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8590, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CurContext->isDependentContext() || B.builtAll()) &&
8590 (0) . __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 8590, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "omp target teams distribute simd loop exprs were not built");
8591
8592  if (!CurContext->isDependentContext()) {
8593    // Finalize the clauses that need pre-built expressions for CodeGen.
8594    for (OMPClause *C : Clauses) {
8595      if (auto *LC = dyn_cast<OMPLinearClause>(C))
8596        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8597                                     B.NumIterations, *this, CurScope,
8598                                     DSAStack))
8599          return StmtError();
8600    }
8601  }
8602
8603  if (checkSimdlenSafelenSpecified(*this, Clauses))
8604    return StmtError();
8605
8606  setFunctionHasBranchProtectedScope();
8607  return OMPTargetTeamsDistributeSimdDirective::Create(
8608      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8609}
8610
8611OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind KindExpr *Expr,
8612                                             SourceLocation StartLoc,
8613                                             SourceLocation LParenLoc,
8614                                             SourceLocation EndLoc) {
8615  OMPClause *Res = nullptr;
8616  switch (Kind) {
8617  case OMPC_final:
8618    Res = ActOnOpenMPFinalClause(ExprStartLocLParenLocEndLoc);
8619    break;
8620  case OMPC_num_threads:
8621    Res = ActOnOpenMPNumThreadsClause(ExprStartLocLParenLocEndLoc);
8622    break;
8623  case OMPC_safelen:
8624    Res = ActOnOpenMPSafelenClause(ExprStartLocLParenLocEndLoc);
8625    break;
8626  case OMPC_simdlen:
8627    Res = ActOnOpenMPSimdlenClause(ExprStartLocLParenLocEndLoc);
8628    break;
8629  case OMPC_allocator:
8630    Res = ActOnOpenMPAllocatorClause(ExprStartLocLParenLocEndLoc);
8631    break;
8632  case OMPC_collapse:
8633    Res = ActOnOpenMPCollapseClause(ExprStartLocLParenLocEndLoc);
8634    break;
8635  case OMPC_ordered:
8636    Res = ActOnOpenMPOrderedClause(StartLocEndLocLParenLocExpr);
8637    break;
8638  case OMPC_device:
8639    Res = ActOnOpenMPDeviceClause(ExprStartLocLParenLocEndLoc);
8640    break;
8641  case OMPC_num_teams:
8642    Res = ActOnOpenMPNumTeamsClause(ExprStartLocLParenLocEndLoc);
8643    break;
8644  case OMPC_thread_limit:
8645    Res = ActOnOpenMPThreadLimitClause(ExprStartLocLParenLocEndLoc);
8646    break;
8647  case OMPC_priority:
8648    Res = ActOnOpenMPPriorityClause(ExprStartLocLParenLocEndLoc);
8649    break;
8650  case OMPC_grainsize:
8651    Res = ActOnOpenMPGrainsizeClause(ExprStartLocLParenLocEndLoc);
8652    break;
8653  case OMPC_num_tasks:
8654    Res = ActOnOpenMPNumTasksClause(ExprStartLocLParenLocEndLoc);
8655    break;
8656  case OMPC_hint:
8657    Res = ActOnOpenMPHintClause(ExprStartLocLParenLocEndLoc);
8658    break;
8659  case OMPC_if:
8660  case OMPC_default:
8661  case OMPC_proc_bind:
8662  case OMPC_schedule:
8663  case OMPC_private:
8664  case OMPC_firstprivate:
8665  case OMPC_lastprivate:
8666  case OMPC_shared:
8667  case OMPC_reduction:
8668  case OMPC_task_reduction:
8669  case OMPC_in_reduction:
8670  case OMPC_linear:
8671  case OMPC_aligned:
8672  case OMPC_copyin:
8673  case OMPC_copyprivate:
8674  case OMPC_nowait:
8675  case OMPC_untied:
8676  case OMPC_mergeable:
8677  case OMPC_threadprivate:
8678  case OMPC_allocate:
8679  case OMPC_flush:
8680  case OMPC_read:
8681  case OMPC_write:
8682  case OMPC_update:
8683  case OMPC_capture:
8684  case OMPC_seq_cst:
8685  case OMPC_depend:
8686  case OMPC_threads:
8687  case OMPC_simd:
8688  case OMPC_map:
8689  case OMPC_nogroup:
8690  case OMPC_dist_schedule:
8691  case OMPC_defaultmap:
8692  case OMPC_unknown:
8693  case OMPC_uniform:
8694  case OMPC_to:
8695  case OMPC_from:
8696  case OMPC_use_device_ptr:
8697  case OMPC_is_device_ptr:
8698  case OMPC_unified_address:
8699  case OMPC_unified_shared_memory:
8700  case OMPC_reverse_offload:
8701  case OMPC_dynamic_allocators:
8702  case OMPC_atomic_default_mem_order:
8703    llvm_unreachable("Clause is not allowed.");
8704  }
8705  return Res;
8706}
8707
8708// An OpenMP directive such as 'target parallel' has two captured regions:
8709// for the 'target' and 'parallel' respectively.  This function returns
8710// the region in which to capture expressions associated with a clause.
8711// A return value of OMPD_unknown signifies that the expression should not
8712// be captured.
8713static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
8714    OpenMPDirectiveKind DKindOpenMPClauseKind CKind,
8715    OpenMPDirectiveKind NameModifier = OMPD_unknown) {
8716  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8717  switch (CKind) {
8718  case OMPC_if:
8719    switch (DKind) {
8720    case OMPD_target_parallel:
8721    case OMPD_target_parallel_for:
8722    case OMPD_target_parallel_for_simd:
8723      // If this clause applies to the nested 'parallel' region, capture within
8724      // the 'target' region, otherwise do not capture.
8725      if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
8726        CaptureRegion = OMPD_target;
8727      break;
8728    case OMPD_target_teams_distribute_parallel_for:
8729    case OMPD_target_teams_distribute_parallel_for_simd:
8730      // If this clause applies to the nested 'parallel' region, capture within
8731      // the 'teams' region, otherwise do not capture.
8732      if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
8733        CaptureRegion = OMPD_teams;
8734      break;
8735    case OMPD_teams_distribute_parallel_for:
8736    case OMPD_teams_distribute_parallel_for_simd:
8737      CaptureRegion = OMPD_teams;
8738      break;
8739    case OMPD_target_update:
8740    case OMPD_target_enter_data:
8741    case OMPD_target_exit_data:
8742      CaptureRegion = OMPD_task;
8743      break;
8744    case OMPD_cancel:
8745    case OMPD_parallel:
8746    case OMPD_parallel_sections:
8747    case OMPD_parallel_for:
8748    case OMPD_parallel_for_simd:
8749    case OMPD_target:
8750    case OMPD_target_simd:
8751    case OMPD_target_teams:
8752    case OMPD_target_teams_distribute:
8753    case OMPD_target_teams_distribute_simd:
8754    case OMPD_distribute_parallel_for:
8755    case OMPD_distribute_parallel_for_simd:
8756    case OMPD_task:
8757    case OMPD_taskloop:
8758    case OMPD_taskloop_simd:
8759    case OMPD_target_data:
8760      // Do not capture if-clause expressions.
8761      break;
8762    case OMPD_threadprivate:
8763    case OMPD_allocate:
8764    case OMPD_taskyield:
8765    case OMPD_barrier:
8766    case OMPD_taskwait:
8767    case OMPD_cancellation_point:
8768    case OMPD_flush:
8769    case OMPD_declare_reduction:
8770    case OMPD_declare_mapper:
8771    case OMPD_declare_simd:
8772    case OMPD_declare_target:
8773    case OMPD_end_declare_target:
8774    case OMPD_teams:
8775    case OMPD_simd:
8776    case OMPD_for:
8777    case OMPD_for_simd:
8778    case OMPD_sections:
8779    case OMPD_section:
8780    case OMPD_single:
8781    case OMPD_master:
8782    case OMPD_critical:
8783    case OMPD_taskgroup:
8784    case OMPD_distribute:
8785    case OMPD_ordered:
8786    case OMPD_atomic:
8787    case OMPD_distribute_simd:
8788    case OMPD_teams_distribute:
8789    case OMPD_teams_distribute_simd:
8790    case OMPD_requires:
8791      llvm_unreachable("Unexpected OpenMP directive with if-clause");
8792    case OMPD_unknown:
8793      llvm_unreachable("Unknown OpenMP directive");
8794    }
8795    break;
8796  case OMPC_num_threads:
8797    switch (DKind) {
8798    case OMPD_target_parallel:
8799    case OMPD_target_parallel_for:
8800    case OMPD_target_parallel_for_simd:
8801      CaptureRegion = OMPD_target;
8802      break;
8803    case OMPD_teams_distribute_parallel_for:
8804    case OMPD_teams_distribute_parallel_for_simd:
8805    case OMPD_target_teams_distribute_parallel_for:
8806    case OMPD_target_teams_distribute_parallel_for_simd:
8807      CaptureRegion = OMPD_teams;
8808      break;
8809    case OMPD_parallel:
8810    case OMPD_parallel_sections:
8811    case OMPD_parallel_for:
8812    case OMPD_parallel_for_simd:
8813    case OMPD_distribute_parallel_for:
8814    case OMPD_distribute_parallel_for_simd:
8815      // Do not capture num_threads-clause expressions.
8816      break;
8817    case OMPD_target_data:
8818    case OMPD_target_enter_data:
8819    case OMPD_target_exit_data:
8820    case OMPD_target_update:
8821    case OMPD_target:
8822    case OMPD_target_simd:
8823    case OMPD_target_teams:
8824    case OMPD_target_teams_distribute:
8825    case OMPD_target_teams_distribute_simd:
8826    case OMPD_cancel:
8827    case OMPD_task:
8828    case OMPD_taskloop:
8829    case OMPD_taskloop_simd:
8830    case OMPD_threadprivate:
8831    case OMPD_allocate:
8832    case OMPD_taskyield:
8833    case OMPD_barrier:
8834    case OMPD_taskwait:
8835    case OMPD_cancellation_point:
8836    case OMPD_flush:
8837    case OMPD_declare_reduction:
8838    case OMPD_declare_mapper:
8839    case OMPD_declare_simd:
8840    case OMPD_declare_target:
8841    case OMPD_end_declare_target:
8842    case OMPD_teams:
8843    case OMPD_simd:
8844    case OMPD_for:
8845    case OMPD_for_simd:
8846    case OMPD_sections:
8847    case OMPD_section:
8848    case OMPD_single:
8849    case OMPD_master:
8850    case OMPD_critical:
8851    case OMPD_taskgroup:
8852    case OMPD_distribute:
8853    case OMPD_ordered:
8854    case OMPD_atomic:
8855    case OMPD_distribute_simd:
8856    case OMPD_teams_distribute:
8857    case OMPD_teams_distribute_simd:
8858    case OMPD_requires:
8859      llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
8860    case OMPD_unknown:
8861      llvm_unreachable("Unknown OpenMP directive");
8862    }
8863    break;
8864  case OMPC_num_teams:
8865    switch (DKind) {
8866    case OMPD_target_teams:
8867    case OMPD_target_teams_distribute:
8868    case OMPD_target_teams_distribute_simd:
8869    case OMPD_target_teams_distribute_parallel_for:
8870    case OMPD_target_teams_distribute_parallel_for_simd:
8871      CaptureRegion = OMPD_target;
8872      break;
8873    case OMPD_teams_distribute_parallel_for:
8874    case OMPD_teams_distribute_parallel_for_simd:
8875    case OMPD_teams:
8876    case OMPD_teams_distribute:
8877    case OMPD_teams_distribute_simd:
8878      // Do not capture num_teams-clause expressions.
8879      break;
8880    case OMPD_distribute_parallel_for:
8881    case OMPD_distribute_parallel_for_simd:
8882    case OMPD_task:
8883    case OMPD_taskloop:
8884    case OMPD_taskloop_simd:
8885    case OMPD_target_data:
8886    case OMPD_target_enter_data:
8887    case OMPD_target_exit_data:
8888    case OMPD_target_update:
8889    case OMPD_cancel:
8890    case OMPD_parallel:
8891    case OMPD_parallel_sections:
8892    case OMPD_parallel_for:
8893    case OMPD_parallel_for_simd:
8894    case OMPD_target:
8895    case OMPD_target_simd:
8896    case OMPD_target_parallel:
8897    case OMPD_target_parallel_for:
8898    case OMPD_target_parallel_for_simd:
8899    case OMPD_threadprivate:
8900    case OMPD_allocate:
8901    case OMPD_taskyield:
8902    case OMPD_barrier:
8903    case OMPD_taskwait:
8904    case OMPD_cancellation_point:
8905    case OMPD_flush:
8906    case OMPD_declare_reduction:
8907    case OMPD_declare_mapper:
8908    case OMPD_declare_simd:
8909    case OMPD_declare_target:
8910    case OMPD_end_declare_target:
8911    case OMPD_simd:
8912    case OMPD_for:
8913    case OMPD_for_simd:
8914    case OMPD_sections:
8915    case OMPD_section:
8916    case OMPD_single:
8917    case OMPD_master:
8918    case OMPD_critical:
8919    case OMPD_taskgroup:
8920    case OMPD_distribute:
8921    case OMPD_ordered:
8922    case OMPD_atomic:
8923    case OMPD_distribute_simd:
8924    case OMPD_requires:
8925      llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8926    case OMPD_unknown:
8927      llvm_unreachable("Unknown OpenMP directive");
8928    }
8929    break;
8930  case OMPC_thread_limit:
8931    switch (DKind) {
8932    case OMPD_target_teams:
8933    case OMPD_target_teams_distribute:
8934    case OMPD_target_teams_distribute_simd:
8935    case OMPD_target_teams_distribute_parallel_for:
8936    case OMPD_target_teams_distribute_parallel_for_simd:
8937      CaptureRegion = OMPD_target;
8938      break;
8939    case OMPD_teams_distribute_parallel_for:
8940    case OMPD_teams_distribute_parallel_for_simd:
8941    case OMPD_teams:
8942    case OMPD_teams_distribute:
8943    case OMPD_teams_distribute_simd:
8944      // Do not capture thread_limit-clause expressions.
8945      break;
8946    case OMPD_distribute_parallel_for:
8947    case OMPD_distribute_parallel_for_simd:
8948    case OMPD_task:
8949    case OMPD_taskloop:
8950    case OMPD_taskloop_simd:
8951    case OMPD_target_data:
8952    case OMPD_target_enter_data:
8953    case OMPD_target_exit_data:
8954    case OMPD_target_update:
8955    case OMPD_cancel:
8956    case OMPD_parallel:
8957    case OMPD_parallel_sections:
8958    case OMPD_parallel_for:
8959    case OMPD_parallel_for_simd:
8960    case OMPD_target:
8961    case OMPD_target_simd:
8962    case OMPD_target_parallel:
8963    case OMPD_target_parallel_for:
8964    case OMPD_target_parallel_for_simd:
8965    case OMPD_threadprivate:
8966    case OMPD_allocate:
8967    case OMPD_taskyield:
8968    case OMPD_barrier:
8969    case OMPD_taskwait:
8970    case OMPD_cancellation_point:
8971    case OMPD_flush:
8972    case OMPD_declare_reduction:
8973    case OMPD_declare_mapper:
8974    case OMPD_declare_simd:
8975    case OMPD_declare_target:
8976    case OMPD_end_declare_target:
8977    case OMPD_simd:
8978    case OMPD_for:
8979    case OMPD_for_simd:
8980    case OMPD_sections:
8981    case OMPD_section:
8982    case OMPD_single:
8983    case OMPD_master:
8984    case OMPD_critical:
8985    case OMPD_taskgroup:
8986    case OMPD_distribute:
8987    case OMPD_ordered:
8988    case OMPD_atomic:
8989    case OMPD_distribute_simd:
8990    case OMPD_requires:
8991      llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
8992    case OMPD_unknown:
8993      llvm_unreachable("Unknown OpenMP directive");
8994    }
8995    break;
8996  case OMPC_schedule:
8997    switch (DKind) {
8998    case OMPD_parallel_for:
8999    case OMPD_parallel_for_simd:
9000    case OMPD_distribute_parallel_for:
9001    case OMPD_distribute_parallel_for_simd:
9002    case OMPD_teams_distribute_parallel_for:
9003    case OMPD_teams_distribute_parallel_for_simd:
9004    case OMPD_target_parallel_for:
9005    case OMPD_target_parallel_for_simd:
9006    case OMPD_target_teams_distribute_parallel_for:
9007    case OMPD_target_teams_distribute_parallel_for_simd:
9008      CaptureRegion = OMPD_parallel;
9009      break;
9010    case OMPD_for:
9011    case OMPD_for_simd:
9012      // Do not capture schedule-clause expressions.
9013      break;
9014    case OMPD_task:
9015    case OMPD_taskloop:
9016    case OMPD_taskloop_simd:
9017    case OMPD_target_data:
9018    case OMPD_target_enter_data:
9019    case OMPD_target_exit_data:
9020    case OMPD_target_update:
9021    case OMPD_teams:
9022    case OMPD_teams_distribute:
9023    case OMPD_teams_distribute_simd:
9024    case OMPD_target_teams_distribute:
9025    case OMPD_target_teams_distribute_simd:
9026    case OMPD_target:
9027    case OMPD_target_simd:
9028    case OMPD_target_parallel:
9029    case OMPD_cancel:
9030    case OMPD_parallel:
9031    case OMPD_parallel_sections:
9032    case OMPD_threadprivate:
9033    case OMPD_allocate:
9034    case OMPD_taskyield:
9035    case OMPD_barrier:
9036    case OMPD_taskwait:
9037    case OMPD_cancellation_point:
9038    case OMPD_flush:
9039    case OMPD_declare_reduction:
9040    case OMPD_declare_mapper:
9041    case OMPD_declare_simd:
9042    case OMPD_declare_target:
9043    case OMPD_end_declare_target:
9044    case OMPD_simd:
9045    case OMPD_sections:
9046    case OMPD_section:
9047    case OMPD_single:
9048    case OMPD_master:
9049    case OMPD_critical:
9050    case OMPD_taskgroup:
9051    case OMPD_distribute:
9052    case OMPD_ordered:
9053    case OMPD_atomic:
9054    case OMPD_distribute_simd:
9055    case OMPD_target_teams:
9056    case OMPD_requires:
9057      llvm_unreachable("Unexpected OpenMP directive with schedule clause");
9058    case OMPD_unknown:
9059      llvm_unreachable("Unknown OpenMP directive");
9060    }
9061    break;
9062  case OMPC_dist_schedule:
9063    switch (DKind) {
9064    case OMPD_teams_distribute_parallel_for:
9065    case OMPD_teams_distribute_parallel_for_simd:
9066    case OMPD_teams_distribute:
9067    case OMPD_teams_distribute_simd:
9068    case OMPD_target_teams_distribute_parallel_for:
9069    case OMPD_target_teams_distribute_parallel_for_simd:
9070    case OMPD_target_teams_distribute:
9071    case OMPD_target_teams_distribute_simd:
9072      CaptureRegion = OMPD_teams;
9073      break;
9074    case OMPD_distribute_parallel_for:
9075    case OMPD_distribute_parallel_for_simd:
9076    case OMPD_distribute:
9077    case OMPD_distribute_simd:
9078      // Do not capture thread_limit-clause expressions.
9079      break;
9080    case OMPD_parallel_for:
9081    case OMPD_parallel_for_simd:
9082    case OMPD_target_parallel_for_simd:
9083    case OMPD_target_parallel_for:
9084    case OMPD_task:
9085    case OMPD_taskloop:
9086    case OMPD_taskloop_simd:
9087    case OMPD_target_data:
9088    case OMPD_target_enter_data:
9089    case OMPD_target_exit_data:
9090    case OMPD_target_update:
9091    case OMPD_teams:
9092    case OMPD_target:
9093    case OMPD_target_simd:
9094    case OMPD_target_parallel:
9095    case OMPD_cancel:
9096    case OMPD_parallel:
9097    case OMPD_parallel_sections:
9098    case OMPD_threadprivate:
9099    case OMPD_allocate:
9100    case OMPD_taskyield:
9101    case OMPD_barrier:
9102    case OMPD_taskwait:
9103    case OMPD_cancellation_point:
9104    case OMPD_flush:
9105    case OMPD_declare_reduction:
9106    case OMPD_declare_mapper:
9107    case OMPD_declare_simd:
9108    case OMPD_declare_target:
9109    case OMPD_end_declare_target:
9110    case OMPD_simd:
9111    case OMPD_for:
9112    case OMPD_for_simd:
9113    case OMPD_sections:
9114    case OMPD_section:
9115    case OMPD_single:
9116    case OMPD_master:
9117    case OMPD_critical:
9118    case OMPD_taskgroup:
9119    case OMPD_ordered:
9120    case OMPD_atomic:
9121    case OMPD_target_teams:
9122    case OMPD_requires:
9123      llvm_unreachable("Unexpected OpenMP directive with schedule clause");
9124    case OMPD_unknown:
9125      llvm_unreachable("Unknown OpenMP directive");
9126    }
9127    break;
9128  case OMPC_device:
9129    switch (DKind) {
9130    case OMPD_target_update:
9131    case OMPD_target_enter_data:
9132    case OMPD_target_exit_data:
9133    case OMPD_target:
9134    case OMPD_target_simd:
9135    case OMPD_target_teams:
9136    case OMPD_target_parallel:
9137    case OMPD_target_teams_distribute:
9138    case OMPD_target_teams_distribute_simd:
9139    case OMPD_target_parallel_for:
9140    case OMPD_target_parallel_for_simd:
9141    case OMPD_target_teams_distribute_parallel_for:
9142    case OMPD_target_teams_distribute_parallel_for_simd:
9143      CaptureRegion = OMPD_task;
9144      break;
9145    case OMPD_target_data:
9146      // Do not capture device-clause expressions.
9147      break;
9148    case OMPD_teams_distribute_parallel_for:
9149    case OMPD_teams_distribute_parallel_for_simd:
9150    case OMPD_teams:
9151    case OMPD_teams_distribute:
9152    case OMPD_teams_distribute_simd:
9153    case OMPD_distribute_parallel_for:
9154    case OMPD_distribute_parallel_for_simd:
9155    case OMPD_task:
9156    case OMPD_taskloop:
9157    case OMPD_taskloop_simd:
9158    case OMPD_cancel:
9159    case OMPD_parallel:
9160    case OMPD_parallel_sections:
9161    case OMPD_parallel_for:
9162    case OMPD_parallel_for_simd:
9163    case OMPD_threadprivate:
9164    case OMPD_allocate:
9165    case OMPD_taskyield:
9166    case OMPD_barrier:
9167    case OMPD_taskwait:
9168    case OMPD_cancellation_point:
9169    case OMPD_flush:
9170    case OMPD_declare_reduction:
9171    case OMPD_declare_mapper:
9172    case OMPD_declare_simd:
9173    case OMPD_declare_target:
9174    case OMPD_end_declare_target:
9175    case OMPD_simd:
9176    case OMPD_for:
9177    case OMPD_for_simd:
9178    case OMPD_sections:
9179    case OMPD_section:
9180    case OMPD_single:
9181    case OMPD_master:
9182    case OMPD_critical:
9183    case OMPD_taskgroup:
9184    case OMPD_distribute:
9185    case OMPD_ordered:
9186    case OMPD_atomic:
9187    case OMPD_distribute_simd:
9188    case OMPD_requires:
9189      llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
9190    case OMPD_unknown:
9191      llvm_unreachable("Unknown OpenMP directive");
9192    }
9193    break;
9194  case OMPC_firstprivate:
9195  case OMPC_lastprivate:
9196  case OMPC_reduction:
9197  case OMPC_task_reduction:
9198  case OMPC_in_reduction:
9199  case OMPC_linear:
9200  case OMPC_default:
9201  case OMPC_proc_bind:
9202  case OMPC_final:
9203  case OMPC_safelen:
9204  case OMPC_simdlen:
9205  case OMPC_allocator:
9206  case OMPC_collapse:
9207  case OMPC_private:
9208  case OMPC_shared:
9209  case OMPC_aligned:
9210  case OMPC_copyin:
9211  case OMPC_copyprivate:
9212  case OMPC_ordered:
9213  case OMPC_nowait:
9214  case OMPC_untied:
9215  case OMPC_mergeable:
9216  case OMPC_threadprivate:
9217  case OMPC_allocate:
9218  case OMPC_flush:
9219  case OMPC_read:
9220  case OMPC_write:
9221  case OMPC_update:
9222  case OMPC_capture:
9223  case OMPC_seq_cst:
9224  case OMPC_depend:
9225  case OMPC_threads:
9226  case OMPC_simd:
9227  case OMPC_map:
9228  case OMPC_priority:
9229  case OMPC_grainsize:
9230  case OMPC_nogroup:
9231  case OMPC_num_tasks:
9232  case OMPC_hint:
9233  case OMPC_defaultmap:
9234  case OMPC_unknown:
9235  case OMPC_uniform:
9236  case OMPC_to:
9237  case OMPC_from:
9238  case OMPC_use_device_ptr:
9239  case OMPC_is_device_ptr:
9240  case OMPC_unified_address:
9241  case OMPC_unified_shared_memory:
9242  case OMPC_reverse_offload:
9243  case OMPC_dynamic_allocators:
9244  case OMPC_atomic_default_mem_order:
9245    llvm_unreachable("Unexpected OpenMP clause.");
9246  }
9247  return CaptureRegion;
9248}
9249
9250OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
9251                                     Expr *ConditionSourceLocation StartLoc,
9252                                     SourceLocation LParenLoc,
9253                                     SourceLocation NameModifierLoc,
9254                                     SourceLocation ColonLoc,
9255                                     SourceLocation EndLoc) {
9256  Expr *ValExpr = Condition;
9257  Stmt *HelperValStmt = nullptr;
9258  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
9259  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
9260      !Condition->isInstantiationDependent() &&
9261      !Condition->containsUnexpandedParameterPack()) {
9262    ExprResult Val = CheckBooleanCondition(StartLocCondition);
9263    if (Val.isInvalid())
9264      return nullptr;
9265
9266    ValExpr = Val.get();
9267
9268    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9269    CaptureRegion =
9270        getOpenMPCaptureRegionForClause(DKindOMPC_ifNameModifier);
9271    if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
9272      ValExpr = MakeFullExpr(ValExpr).get();
9273      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9274      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9275      HelperValStmt = buildPreInits(Context, Captures);
9276    }
9277  }
9278
9279  return new (Context)
9280      OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
9281                  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
9282}
9283
9284OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
9285                                        SourceLocation StartLoc,
9286                                        SourceLocation LParenLoc,
9287                                        SourceLocation EndLoc) {
9288  Expr *ValExpr = Condition;
9289  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
9290      !Condition->isInstantiationDependent() &&
9291      !Condition->containsUnexpandedParameterPack()) {
9292    ExprResult Val = CheckBooleanCondition(StartLocCondition);
9293    if (Val.isInvalid())
9294      return nullptr;
9295
9296    ValExpr = MakeFullExpr(Val.get()).get();
9297  }
9298
9299  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
9300}
9301ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
9302                                                        Expr *Op) {
9303  if (!Op)
9304    return ExprError();
9305
9306  class IntConvertDiagnoser : public ICEConvertDiagnoser {
9307  public:
9308    IntConvertDiagnoser()
9309        : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ falsefalsetrue) {}
9310    SemaDiagnosticBuilder diagnoseNotInt(Sema &SSourceLocation Loc,
9311                                         QualType T) override {
9312      return S.Diag(Loc, diag::err_omp_not_integral) << T;
9313    }
9314    SemaDiagnosticBuilder diagnoseIncomplete(Sema &SSourceLocation Loc,
9315                                             QualType T) override {
9316      return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
9317    }
9318    SemaDiagnosticBuilder diagnoseExplicitConv(Sema &SSourceLocation Loc,
9319                                               QualType T,
9320                                               QualType ConvTy) override {
9321      return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
9322    }
9323    SemaDiagnosticBuilder noteExplicitConv(Sema &SCXXConversionDecl *Conv,
9324                                           QualType ConvTy) override {
9325      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
9326             << ConvTy->isEnumeralType() << ConvTy;
9327    }
9328    SemaDiagnosticBuilder diagnoseAmbiguous(Sema &SSourceLocation Loc,
9329                                            QualType T) override {
9330      return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
9331    }
9332    SemaDiagnosticBuilder noteAmbiguous(Sema &SCXXConversionDecl *Conv,
9333                                        QualType ConvTy) override {
9334      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
9335             << ConvTy->isEnumeralType() << ConvTy;
9336    }
9337    SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocationQualType,
9338                                             QualType) override {
9339      llvm_unreachable("conversion functions are permitted");
9340    }
9341  } ConvertDiagnoser;
9342  return PerformContextualImplicitConversion(LocOpConvertDiagnoser);
9343}
9344
9345static bool isNonNegativeIntegerValue(Expr *&ValExprSema &SemaRef,
9346                                      OpenMPClauseKind CKind,
9347                                      bool StrictlyPositive) {
9348  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
9349      !ValExpr->isInstantiationDependent()) {
9350    SourceLocation Loc = ValExpr->getExprLoc();
9351    ExprResult Value =
9352        SemaRef.PerformOpenMPImplicitIntegerConversion(LocValExpr);
9353    if (Value.isInvalid())
9354      return false;
9355
9356    ValExpr = Value.get();
9357    // The expression must evaluate to a non-negative integer value.
9358    llvm::APSInt Result;
9359    if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
9360        Result.isSigned() &&
9361        !((!StrictlyPositive && Result.isNonNegative()) ||
9362          (StrictlyPositive && Result.isStrictlyPositive()))) {
9363      SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
9364          << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
9365          << ValExpr->getSourceRange();
9366      return false;
9367    }
9368  }
9369  return true;
9370}
9371
9372OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
9373                                             SourceLocation StartLoc,
9374                                             SourceLocation LParenLoc,
9375                                             SourceLocation EndLoc) {
9376  Expr *ValExpr = NumThreads;
9377  Stmt *HelperValStmt = nullptr;
9378
9379  // OpenMP [2.5, Restrictions]
9380  //  The num_threads expression must evaluate to a positive integer value.
9381  if (!isNonNegativeIntegerValue(ValExpr*thisOMPC_num_threads,
9382                                 /*StrictlyPositive=*/true))
9383    return nullptr;
9384
9385  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9386  OpenMPDirectiveKind CaptureRegion =
9387      getOpenMPCaptureRegionForClause(DKindOMPC_num_threads);
9388  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
9389    ValExpr = MakeFullExpr(ValExpr).get();
9390    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9391    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9392    HelperValStmt = buildPreInits(Context, Captures);
9393  }
9394
9395  return new (Context) OMPNumThreadsClause(
9396      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
9397}
9398
9399ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
9400                                                       OpenMPClauseKind CKind,
9401                                                       bool StrictlyPositive) {
9402  if (!E)
9403    return ExprError();
9404  if (E->isValueDependent() || E->isTypeDependent() ||
9405      E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
9406    return E;
9407  llvm::APSInt Result;
9408  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
9409  if (ICE.isInvalid())
9410    return ExprError();
9411  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
9412      (!StrictlyPositive && !Result.isNonNegative())) {
9413    Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
9414        << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
9415        << E->getSourceRange();
9416    return ExprError();
9417  }
9418  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
9419    Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
9420        << E->getSourceRange();
9421    return ExprError();
9422  }
9423  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
9424    DSAStack->setAssociatedLoops(Result.getExtValue());
9425  else if (CKind == OMPC_ordered)
9426    DSAStack->setAssociatedLoops(Result.getExtValue());
9427  return ICE;
9428}
9429
9430OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *LenSourceLocation StartLoc,
9431                                          SourceLocation LParenLoc,
9432                                          SourceLocation EndLoc) {
9433  // OpenMP [2.8.1, simd construct, Description]
9434  // The parameter of the safelen clause must be a constant
9435  // positive integer expression.
9436  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(LenOMPC_safelen);
9437  if (Safelen.isInvalid())
9438    return nullptr;
9439  return new (Context)
9440      OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
9441}
9442
9443OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *LenSourceLocation StartLoc,
9444                                          SourceLocation LParenLoc,
9445                                          SourceLocation EndLoc) {
9446  // OpenMP [2.8.1, simd construct, Description]
9447  // The parameter of the simdlen clause must be a constant
9448  // positive integer expression.
9449  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(LenOMPC_simdlen);
9450  if (Simdlen.isInvalid())
9451    return nullptr;
9452  return new (Context)
9453      OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
9454}
9455
9456/// Tries to find omp_allocator_handle_t type.
9457static bool findOMPAllocatorHandleT(Sema &SSourceLocation Loc,
9458                                    DSAStackTy *Stack) {
9459  QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
9460  if (!OMPAllocatorHandleT.isNull())
9461    return true;
9462  // Build the predefined allocator expressions.
9463  bool ErrorFound = false;
9464  for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
9465       I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
9466    auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
9467    StringRef Allocator =
9468        OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
9469    DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
9470    auto *VD = dyn_cast_or_null<ValueDecl>(
9471        S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
9472    if (!VD) {
9473      ErrorFound = true;
9474      break;
9475    }
9476    QualType AllocatorType =
9477        VD->getType().getNonLValueExprType(S.getASTContext());
9478    ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
9479    if (!Res.isUsable()) {
9480      ErrorFound = true;
9481      break;
9482    }
9483    if (OMPAllocatorHandleT.isNull())
9484      OMPAllocatorHandleT = AllocatorType;
9485    if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
9486      ErrorFound = true;
9487      break;
9488    }
9489    Stack->setAllocator(AllocatorKind, Res.get());
9490  }
9491  if (ErrorFound) {
9492    S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
9493    return false;
9494  }
9495  OMPAllocatorHandleT.addConst();
9496  Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
9497  return true;
9498}
9499
9500OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *ASourceLocation StartLoc,
9501                                            SourceLocation LParenLoc,
9502                                            SourceLocation EndLoc) {
9503  // OpenMP [2.11.3, allocate Directive, Description]
9504  // allocator is an expression of omp_allocator_handle_t type.
9505  if (!findOMPAllocatorHandleT(*thisA->getExprLoc(), DSAStack))
9506    return nullptr;
9507
9508  ExprResult Allocator = DefaultLvalueConversion(A);
9509  if (Allocator.isInvalid())
9510    return nullptr;
9511  Allocator = PerformImplicitConversion(Allocator.get(),
9512                                        DSAStack->getOMPAllocatorHandleT(),
9513                                        Sema::AA_Initializing,
9514                                        /*AllowExplicit=*/true);
9515  if (Allocator.isInvalid())
9516    return nullptr;
9517  return new (Context)
9518      OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
9519}
9520
9521OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
9522                                           SourceLocation StartLoc,
9523                                           SourceLocation LParenLoc,
9524                                           SourceLocation EndLoc) {
9525  // OpenMP [2.7.1, loop construct, Description]
9526  // OpenMP [2.8.1, simd construct, Description]
9527  // OpenMP [2.9.6, distribute construct, Description]
9528  // The parameter of the collapse clause must be a constant
9529  // positive integer expression.
9530  ExprResult NumForLoopsResult =
9531      VerifyPositiveIntegerConstantInClause(NumForLoopsOMPC_collapse);
9532  if (NumForLoopsResult.isInvalid())
9533    return nullptr;
9534  return new (Context)
9535      OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
9536}
9537
9538OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
9539                                          SourceLocation EndLoc,
9540                                          SourceLocation LParenLoc,
9541                                          Expr *NumForLoops) {
9542  // OpenMP [2.7.1, loop construct, Description]
9543  // OpenMP [2.8.1, simd construct, Description]
9544  // OpenMP [2.9.6, distribute construct, Description]
9545  // The parameter of the ordered clause must be a constant
9546  // positive integer expression if any.
9547  if (NumForLoops && LParenLoc.isValid()) {
9548    ExprResult NumForLoopsResult =
9549        VerifyPositiveIntegerConstantInClause(NumForLoopsOMPC_ordered);
9550    if (NumForLoopsResult.isInvalid())
9551      return nullptr;
9552    NumForLoops = NumForLoopsResult.get();
9553  } else {
9554    NumForLoops = nullptr;
9555  }
9556  auto *Clause = OMPOrderedClause::Create(
9557      ContextNumForLoopsNumForLoops ? DSAStack->getAssociatedLoops() : 0,
9558      StartLocLParenLocEndLoc);
9559  DSAStack->setOrderedRegion(/*IsOrdered=*/trueNumForLoopsClause);
9560  return Clause;
9561}
9562
9563OMPClause *Sema::ActOnOpenMPSimpleClause(
9564    OpenMPClauseKind Kindunsigned ArgumentSourceLocation ArgumentLoc,
9565    SourceLocation StartLocSourceLocation LParenLocSourceLocation EndLoc) {
9566  OMPClause *Res = nullptr;
9567  switch (Kind) {
9568  case OMPC_default:
9569    Res =
9570        ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
9571                                 ArgumentLocStartLocLParenLocEndLoc);
9572    break;
9573  case OMPC_proc_bind:
9574    Res = ActOnOpenMPProcBindClause(
9575        static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLocStartLoc,
9576        LParenLocEndLoc);
9577    break;
9578  case OMPC_atomic_default_mem_order:
9579    Res = ActOnOpenMPAtomicDefaultMemOrderClause(
9580        static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
9581        ArgumentLocStartLocLParenLocEndLoc);
9582    break;
9583  case OMPC_if:
9584  case OMPC_final:
9585  case OMPC_num_threads:
9586  case OMPC_safelen:
9587  case OMPC_simdlen:
9588  case OMPC_allocator:
9589  case OMPC_collapse:
9590  case OMPC_schedule:
9591  case OMPC_private:
9592  case OMPC_firstprivate:
9593  case OMPC_lastprivate:
9594  case OMPC_shared:
9595  case OMPC_reduction:
9596  case OMPC_task_reduction:
9597  case OMPC_in_reduction:
9598  case OMPC_linear:
9599  case OMPC_aligned:
9600  case OMPC_copyin:
9601  case OMPC_copyprivate:
9602  case OMPC_ordered:
9603  case OMPC_nowait:
9604  case OMPC_untied:
9605  case OMPC_mergeable:
9606  case OMPC_threadprivate:
9607  case OMPC_allocate:
9608  case OMPC_flush:
9609  case OMPC_read:
9610  case OMPC_write:
9611  case OMPC_update:
9612  case OMPC_capture:
9613  case OMPC_seq_cst:
9614  case OMPC_depend:
9615  case OMPC_device:
9616  case OMPC_threads:
9617  case OMPC_simd:
9618  case OMPC_map:
9619  case OMPC_num_teams:
9620  case OMPC_thread_limit:
9621  case OMPC_priority:
9622  case OMPC_grainsize:
9623  case OMPC_nogroup:
9624  case OMPC_num_tasks:
9625  case OMPC_hint:
9626  case OMPC_dist_schedule:
9627  case OMPC_defaultmap:
9628  case OMPC_unknown:
9629  case OMPC_uniform:
9630  case OMPC_to:
9631  case OMPC_from:
9632  case OMPC_use_device_ptr:
9633  case OMPC_is_device_ptr:
9634  case OMPC_unified_address:
9635  case OMPC_unified_shared_memory:
9636  case OMPC_reverse_offload:
9637  case OMPC_dynamic_allocators:
9638    llvm_unreachable("Clause is not allowed.");
9639  }
9640  return Res;
9641}
9642
9643static std::string
9644getListOfPossibleValues(OpenMPClauseKind Kunsigned Firstunsigned Last,
9645                        ArrayRef<unsignedExclude = llvm::None) {
9646  SmallString<256Buffer;
9647  llvm::raw_svector_ostream Out(Buffer);
9648  unsigned Bound = Last >= 2 ? Last - 2 : 0;
9649  unsigned Skipped = Exclude.size();
9650  auto S = Exclude.begin(), E = Exclude.end();
9651  for (unsigned I = FirstI < Last; ++I) {
9652    if (std::find(S, E, I) != E) {
9653      --Skipped;
9654      continue;
9655    }
9656    Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
9657    if (I == Bound - Skipped)
9658      Out << " or ";
9659    else if (I != Bound + 1 - Skipped)
9660      Out << ", ";
9661  }
9662  return Out.str();
9663}
9664
9665OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
9666                                          SourceLocation KindKwLoc,
9667                                          SourceLocation StartLoc,
9668                                          SourceLocation LParenLoc,
9669                                          SourceLocation EndLoc) {
9670  if (Kind == OMPC_DEFAULT_unknown) {
9671    static_assert(OMPC_DEFAULT_unknown > 0,
9672                  "OMPC_DEFAULT_unknown not greater than 0");
9673    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9674        << getListOfPossibleValues(OMPC_default, /*First=*/0,
9675                                   /*Last=*/OMPC_DEFAULT_unknown)
9676        << getOpenMPClauseName(OMPC_default);
9677    return nullptr;
9678  }
9679  switch (Kind) {
9680  case OMPC_DEFAULT_none:
9681    DSAStack->setDefaultDSANone(KindKwLoc);
9682    break;
9683  case OMPC_DEFAULT_shared:
9684    DSAStack->setDefaultDSAShared(KindKwLoc);
9685    break;
9686  case OMPC_DEFAULT_unknown:
9687    llvm_unreachable("Clause kind is not allowed.");
9688    break;
9689  }
9690  return new (Context)
9691      OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
9692}
9693
9694OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
9695                                           SourceLocation KindKwLoc,
9696                                           SourceLocation StartLoc,
9697                                           SourceLocation LParenLoc,
9698                                           SourceLocation EndLoc) {
9699  if (Kind == OMPC_PROC_BIND_unknown) {
9700    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9701        << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
9702                                   /*Last=*/OMPC_PROC_BIND_unknown)
9703        << getOpenMPClauseName(OMPC_proc_bind);
9704    return nullptr;
9705  }
9706  return new (Context)
9707      OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
9708}
9709
9710OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
9711    OpenMPAtomicDefaultMemOrderClauseKind KindSourceLocation KindKwLoc,
9712    SourceLocation StartLocSourceLocation LParenLocSourceLocation EndLoc) {
9713  if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
9714    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9715        << getListOfPossibleValues(
9716               OMPC_atomic_default_mem_order, /*First=*/0,
9717               /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
9718        << getOpenMPClauseName(OMPC_atomic_default_mem_order);
9719    return nullptr;
9720  }
9721  return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
9722                                                      LParenLoc, EndLoc);
9723}
9724
9725OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
9726    OpenMPClauseKind KindArrayRef<unsignedArgumentExpr *Expr,
9727    SourceLocation StartLocSourceLocation LParenLoc,
9728    ArrayRef<SourceLocationArgumentLocSourceLocation DelimLoc,
9729    SourceLocation EndLoc) {
9730  OMPClause *Res = nullptr;
9731  switch (Kind) {
9732  case OMPC_schedule:
9733    enum { Modifier1Modifier2ScheduleKindNumberOfElements };
9734    assert(Argument.size() == NumberOfElements &&
9735           ArgumentLoc.size() == NumberOfElements);
9736    Res = ActOnOpenMPScheduleClause(
9737        static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
9738        static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
9739        static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
9740        StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
9741        ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
9742    break;
9743  case OMPC_if:
9744    assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
9745    Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
9746                              Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
9747                              DelimLoc, EndLoc);
9748    break;
9749  case OMPC_dist_schedule:
9750    Res = ActOnOpenMPDistScheduleClause(
9751        static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
9752        StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
9753    break;
9754  case OMPC_defaultmap:
9755    enum { ModifierDefaultmapKind };
9756    Res = ActOnOpenMPDefaultmapClause(
9757        static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
9758        static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
9759        StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
9760        EndLoc);
9761    break;
9762  case OMPC_final:
9763  case OMPC_num_threads:
9764  case OMPC_safelen:
9765  case OMPC_simdlen:
9766  case OMPC_allocator:
9767  case OMPC_collapse:
9768  case OMPC_default:
9769  case OMPC_proc_bind:
9770  case OMPC_private:
9771  case OMPC_firstprivate:
9772  case OMPC_lastprivate:
9773  case OMPC_shared:
9774  case OMPC_reduction:
9775  case OMPC_task_reduction:
9776  case OMPC_in_reduction:
9777  case OMPC_linear:
9778  case OMPC_aligned:
9779  case OMPC_copyin:
9780  case OMPC_copyprivate:
9781  case OMPC_ordered:
9782  case OMPC_nowait:
9783  case OMPC_untied:
9784  case OMPC_mergeable:
9785  case OMPC_threadprivate:
9786  case OMPC_allocate:
9787  case OMPC_flush:
9788  case OMPC_read:
9789  case OMPC_write:
9790  case OMPC_update:
9791  case OMPC_capture:
9792  case OMPC_seq_cst:
9793  case OMPC_depend:
9794  case OMPC_device:
9795  case OMPC_threads:
9796  case OMPC_simd:
9797  case OMPC_map:
9798  case OMPC_num_teams:
9799  case OMPC_thread_limit:
9800  case OMPC_priority:
9801  case OMPC_grainsize:
9802  case OMPC_nogroup:
9803  case OMPC_num_tasks:
9804  case OMPC_hint:
9805  case OMPC_unknown:
9806  case OMPC_uniform:
9807  case OMPC_to:
9808  case OMPC_from:
9809  case OMPC_use_device_ptr:
9810  case OMPC_is_device_ptr:
9811  case OMPC_unified_address:
9812  case OMPC_unified_shared_memory:
9813  case OMPC_reverse_offload:
9814  case OMPC_dynamic_allocators:
9815  case OMPC_atomic_default_mem_order:
9816    llvm_unreachable("Clause is not allowed.");
9817  }
9818  return Res;
9819}
9820
9821static bool checkScheduleModifiers(Sema &SOpenMPScheduleClauseModifier M1,
9822                                   OpenMPScheduleClauseModifier M2,
9823                                   SourceLocation M1LocSourceLocation M2Loc) {
9824  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
9825    SmallVector<unsigned2Excluded;
9826    if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
9827      Excluded.push_back(M2);
9828    if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
9829      Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
9830    if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
9831      Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
9832    S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
9833        << getListOfPossibleValues(OMPC_schedule,
9834                                   /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
9835                                   /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
9836                                   Excluded)
9837        << getOpenMPClauseName(OMPC_schedule);
9838    return true;
9839  }
9840  return false;
9841}
9842
9843OMPClause *Sema::ActOnOpenMPScheduleClause(
9844    OpenMPScheduleClauseModifier M1OpenMPScheduleClauseModifier M2,
9845    OpenMPScheduleClauseKind KindExpr *ChunkSizeSourceLocation StartLoc,
9846    SourceLocation LParenLocSourceLocation M1LocSourceLocation M2Loc,
9847    SourceLocation KindLocSourceLocation CommaLocSourceLocation EndLoc) {
9848  if (checkScheduleModifiers(*thisM1M2M1LocM2Loc) ||
9849      checkScheduleModifiers(*thisM2M1M2LocM1Loc))
9850    return nullptr;
9851  // OpenMP, 2.7.1, Loop Construct, Restrictions
9852  // Either the monotonic modifier or the nonmonotonic modifier can be specified
9853  // but not both.
9854  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
9855      (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
9856       M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
9857      (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
9858       M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
9859    Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
9860        << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
9861        << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
9862    return nullptr;
9863  }
9864  if (Kind == OMPC_SCHEDULE_unknown) {
9865    std::string Values;
9866    if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
9867      unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
9868      Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
9869                                       /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
9870                                       Exclude);
9871    } else {
9872      Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
9873                                       /*Last=*/OMPC_SCHEDULE_unknown);
9874    }
9875    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
9876        << Values << getOpenMPClauseName(OMPC_schedule);
9877    return nullptr;
9878  }
9879  // OpenMP, 2.7.1, Loop Construct, Restrictions
9880  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
9881  // schedule(guided).
9882  if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
9883       M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
9884      Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
9885    Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
9886         diag::err_omp_schedule_nonmonotonic_static);
9887    return nullptr;
9888  }
9889  Expr *ValExpr = ChunkSize;
9890  Stmt *HelperValStmt = nullptr;
9891  if (ChunkSize) {
9892    if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
9893        !ChunkSize->isInstantiationDependent() &&
9894        !ChunkSize->containsUnexpandedParameterPack()) {
9895      SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
9896      ExprResult Val =
9897          PerformOpenMPImplicitIntegerConversion(ChunkSizeLocChunkSize);
9898      if (Val.isInvalid())
9899        return nullptr;
9900
9901      ValExpr = Val.get();
9902
9903      // OpenMP [2.7.1, Restrictions]
9904      //  chunk_size must be a loop invariant integer expression with a positive
9905      //  value.
9906      llvm::APSInt Result;
9907      if (ValExpr->isIntegerConstantExpr(Result, Context)) {
9908        if (Result.isSigned() && !Result.isStrictlyPositive()) {
9909          Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
9910              << "schedule" << 1 << ChunkSize->getSourceRange();
9911          return nullptr;
9912        }
9913      } else if (getOpenMPCaptureRegionForClause(
9914                     DSAStack->getCurrentDirective(), OMPC_schedule) !=
9915                     OMPD_unknown &&
9916                 !CurContext->isDependentContext()) {
9917        ValExpr = MakeFullExpr(ValExpr).get();
9918        llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9919        ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9920        HelperValStmt = buildPreInits(Context, Captures);
9921      }
9922    }
9923  }
9924
9925  return new (Context)
9926      OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
9927                        ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
9928}
9929
9930OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
9931                                   SourceLocation StartLoc,
9932                                   SourceLocation EndLoc) {
9933  OMPClause *Res = nullptr;
9934  switch (Kind) {
9935  case OMPC_ordered:
9936    Res = ActOnOpenMPOrderedClause(StartLocEndLoc);
9937    break;
9938  case OMPC_nowait:
9939    Res = ActOnOpenMPNowaitClause(StartLocEndLoc);
9940    break;
9941  case OMPC_untied:
9942    Res = ActOnOpenMPUntiedClause(StartLocEndLoc);
9943    break;
9944  case OMPC_mergeable:
9945    Res = ActOnOpenMPMergeableClause(StartLocEndLoc);
9946    break;
9947  case OMPC_read:
9948    Res = ActOnOpenMPReadClause(StartLocEndLoc);
9949    break;
9950  case OMPC_write:
9951    Res = ActOnOpenMPWriteClause(StartLocEndLoc);
9952    break;
9953  case OMPC_update:
9954    Res = ActOnOpenMPUpdateClause(StartLocEndLoc);
9955    break;
9956  case OMPC_capture:
9957    Res = ActOnOpenMPCaptureClause(StartLocEndLoc);
9958    break;
9959  case OMPC_seq_cst:
9960    Res = ActOnOpenMPSeqCstClause(StartLocEndLoc);
9961    break;
9962  case OMPC_threads:
9963    Res = ActOnOpenMPThreadsClause(StartLocEndLoc);
9964    break;
9965  case OMPC_simd:
9966    Res = ActOnOpenMPSIMDClause(StartLocEndLoc);
9967    break;
9968  case OMPC_nogroup:
9969    Res = ActOnOpenMPNogroupClause(StartLocEndLoc);
9970    break;
9971  case OMPC_unified_address:
9972    Res = ActOnOpenMPUnifiedAddressClause(StartLocEndLoc);
9973    break;
9974  case OMPC_unified_shared_memory:
9975    Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLocEndLoc);
9976    break;
9977  case OMPC_reverse_offload:
9978    Res = ActOnOpenMPReverseOffloadClause(StartLocEndLoc);
9979    break;
9980  case OMPC_dynamic_allocators:
9981    Res = ActOnOpenMPDynamicAllocatorsClause(StartLocEndLoc);
9982    break;
9983  case OMPC_if:
9984  case OMPC_final:
9985  case OMPC_num_threads:
9986  case OMPC_safelen:
9987  case OMPC_simdlen:
9988  case OMPC_allocator:
9989  case OMPC_collapse:
9990  case OMPC_schedule:
9991  case OMPC_private:
9992  case OMPC_firstprivate:
9993  case OMPC_lastprivate:
9994  case OMPC_shared:
9995  case OMPC_reduction:
9996  case OMPC_task_reduction:
9997  case OMPC_in_reduction:
9998  case OMPC_linear:
9999  case OMPC_aligned:
10000  case OMPC_copyin:
10001  case OMPC_copyprivate:
10002  case OMPC_default:
10003  case OMPC_proc_bind:
10004  case OMPC_threadprivate:
10005  case OMPC_allocate:
10006  case OMPC_flush:
10007  case OMPC_depend:
10008  case OMPC_device:
10009  case OMPC_map:
10010  case OMPC_num_teams:
10011  case OMPC_thread_limit:
10012  case OMPC_priority:
10013  case OMPC_grainsize:
10014  case OMPC_num_tasks:
10015  case OMPC_hint:
10016  case OMPC_dist_schedule:
10017  case OMPC_defaultmap:
10018  case OMPC_unknown:
10019  case OMPC_uniform:
10020  case OMPC_to:
10021  case OMPC_from:
10022  case OMPC_use_device_ptr:
10023  case OMPC_is_device_ptr:
10024  case OMPC_atomic_default_mem_order:
10025    llvm_unreachable("Clause is not allowed.");
10026  }
10027  return Res;
10028}
10029
10030OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
10031                                         SourceLocation EndLoc) {
10032  DSAStack->setNowaitRegion();
10033  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
10034}
10035
10036OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
10037                                         SourceLocation EndLoc) {
10038  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
10039}
10040
10041OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
10042                                            SourceLocation EndLoc) {
10043  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
10044}
10045
10046OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
10047                                       SourceLocation EndLoc) {
10048  return new (Context) OMPReadClause(StartLoc, EndLoc);
10049}
10050
10051OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
10052                                        SourceLocation EndLoc) {
10053  return new (Context) OMPWriteClause(StartLoc, EndLoc);
10054}
10055
10056OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
10057                                         SourceLocation EndLoc) {
10058  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
10059}
10060
10061OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
10062                                          SourceLocation EndLoc) {
10063  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
10064}
10065
10066OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
10067                                         SourceLocation EndLoc) {
10068  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
10069}
10070
10071OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
10072                                          SourceLocation EndLoc) {
10073  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
10074}
10075
10076OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
10077                                       SourceLocation EndLoc) {
10078  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
10079}
10080
10081OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
10082                                          SourceLocation EndLoc) {
10083  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
10084}
10085
10086OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
10087                                                 SourceLocation EndLoc) {
10088  return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
10089}
10090
10091OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
10092                                                      SourceLocation EndLoc) {
10093  return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
10094}
10095
10096OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
10097                                                 SourceLocation EndLoc) {
10098  return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
10099}
10100
10101OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
10102                                                    SourceLocation EndLoc) {
10103  return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
10104}
10105
10106OMPClause *Sema::ActOnOpenMPVarListClause(
10107    OpenMPClauseKind KindArrayRef<Expr *> VarListExpr *TailExpr,
10108    const OMPVarListLocTy &LocsSourceLocation ColonLoc,
10109    CXXScopeSpec &ReductionOrMapperIdScopeSpec,
10110    DeclarationNameInfo &ReductionOrMapperIdOpenMPDependClauseKind DepKind,
10111    OpenMPLinearClauseKind LinKind,
10112    ArrayRef<OpenMPMapModifierKindMapTypeModifiers,
10113    ArrayRef<SourceLocationMapTypeModifiersLocOpenMPMapClauseKind MapType,
10114    bool IsMapTypeImplicitSourceLocation DepLinMapLoc) {
10115  SourceLocation StartLoc = Locs.StartLoc;
10116  SourceLocation LParenLoc = Locs.LParenLoc;
10117  SourceLocation EndLoc = Locs.EndLoc;
10118  OMPClause *Res = nullptr;
10119  switch (Kind) {
10120  case OMPC_private:
10121    Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10122    break;
10123  case OMPC_firstprivate:
10124    Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10125    break;
10126  case OMPC_lastprivate:
10127    Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10128    break;
10129  case OMPC_shared:
10130    Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
10131    break;
10132  case OMPC_reduction:
10133    Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
10134                                     EndLoc, ReductionOrMapperIdScopeSpec,
10135                                     ReductionOrMapperId);
10136    break;
10137  case OMPC_task_reduction:
10138    Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
10139                                         EndLoc, ReductionOrMapperIdScopeSpec,
10140                                         ReductionOrMapperId);
10141    break;
10142  case OMPC_in_reduction:
10143    Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
10144                                       EndLoc, ReductionOrMapperIdScopeSpec,
10145                                       ReductionOrMapperId);
10146    break;
10147  case OMPC_linear:
10148    Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
10149                                  LinKind, DepLinMapLoc, ColonLoc, EndLoc);
10150    break;
10151  case OMPC_aligned:
10152    Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
10153                                   ColonLoc, EndLoc);
10154    break;
10155  case OMPC_copyin:
10156    Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
10157    break;
10158  case OMPC_copyprivate:
10159    Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10160    break;
10161  case OMPC_flush:
10162    Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
10163    break;
10164  case OMPC_depend:
10165    Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
10166                                  StartLoc, LParenLoc, EndLoc);
10167    break;
10168  case OMPC_map:
10169    Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc,
10170                               ReductionOrMapperIdScopeSpec,
10171                               ReductionOrMapperId, MapType, IsMapTypeImplicit,
10172                               DepLinMapLoc, ColonLoc, VarList, Locs);
10173    break;
10174  case OMPC_to:
10175    Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
10176                              ReductionOrMapperId, Locs);
10177    break;
10178  case OMPC_from:
10179    Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
10180                                ReductionOrMapperId, Locs);
10181    break;
10182  case OMPC_use_device_ptr:
10183    Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
10184    break;
10185  case OMPC_is_device_ptr:
10186    Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
10187    break;
10188  case OMPC_allocate:
10189    Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
10190                                    ColonLoc, EndLoc);
10191    break;
10192  case OMPC_if:
10193  case OMPC_final:
10194  case OMPC_num_threads:
10195  case OMPC_safelen:
10196  case OMPC_simdlen:
10197  case OMPC_allocator:
10198  case OMPC_collapse:
10199  case OMPC_default:
10200  case OMPC_proc_bind:
10201  case OMPC_schedule:
10202  case OMPC_ordered:
10203  case OMPC_nowait:
10204  case OMPC_untied:
10205  case OMPC_mergeable:
10206  case OMPC_threadprivate:
10207  case OMPC_read:
10208  case OMPC_write:
10209  case OMPC_update:
10210  case OMPC_capture:
10211  case OMPC_seq_cst:
10212  case OMPC_device:
10213  case OMPC_threads:
10214  case OMPC_simd:
10215  case OMPC_num_teams:
10216  case OMPC_thread_limit:
10217  case OMPC_priority:
10218  case OMPC_grainsize:
10219  case OMPC_nogroup:
10220  case OMPC_num_tasks:
10221  case OMPC_hint:
10222  case OMPC_dist_schedule:
10223  case OMPC_defaultmap:
10224  case OMPC_unknown:
10225  case OMPC_uniform:
10226  case OMPC_unified_address:
10227  case OMPC_unified_shared_memory:
10228  case OMPC_reverse_offload:
10229  case OMPC_dynamic_allocators:
10230  case OMPC_atomic_default_mem_order:
10231    llvm_unreachable("Clause is not allowed.");
10232  }
10233  return Res;
10234}
10235
10236ExprResult Sema::getOpenMPCapturedExpr(VarDecl *CaptureExprValueKind VK,
10237                                       ExprObjectKind OKSourceLocation Loc) {
10238  ExprResult Res = BuildDeclRefExpr(
10239      CaptureCapture->getType().getNonReferenceType(), VK_LValueLoc);
10240  if (!Res.isUsable())
10241    return ExprError();
10242  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
10243    Res = CreateBuiltinUnaryOp(LocUO_DerefRes.get());
10244    if (!Res.isUsable())
10245      return ExprError();
10246  }
10247  if (VK != VK_LValue && Res.get()->isGLValue()) {
10248    Res = DefaultLvalueConversion(Res.get());
10249    if (!Res.isUsable())
10250      return ExprError();
10251  }
10252  return Res;
10253}
10254
10255static std::pair<ValueDecl *, bool>
10256getPrivateItem(Sema &SExpr *&RefExprSourceLocation &ELoc,
10257               SourceRange &ERangebool AllowArraySection = false) {
10258  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
10259      RefExpr->containsUnexpandedParameterPack())
10260    return std::make_pair(nullptrtrue);
10261
10262  // OpenMP [3.1, C/C++]
10263  //  A list item is a variable name.
10264  // OpenMP  [2.9.3.3, Restrictions, p.1]
10265  //  A variable that is part of another variable (as an array or
10266  //  structure element) cannot appear in a private clause.
10267  RefExpr = RefExpr->IgnoreParens();
10268  enum {
10269    NoArrayExpr = -1,
10270    ArraySubscript = 0,
10271    OMPArraySection = 1
10272  } IsArrayExpr = NoArrayExpr;
10273  if (AllowArraySection) {
10274    if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
10275      Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
10276      while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
10277        Base = TempASE->getBase()->IgnoreParenImpCasts();
10278      RefExpr = Base;
10279      IsArrayExpr = ArraySubscript;
10280    } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
10281      Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
10282      while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
10283        Base = TempOASE->getBase()->IgnoreParenImpCasts();
10284      while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
10285        Base = TempASE->getBase()->IgnoreParenImpCasts();
10286      RefExpr = Base;
10287      IsArrayExpr = OMPArraySection;
10288    }
10289  }
10290  ELoc = RefExpr->getExprLoc();
10291  ERange = RefExpr->getSourceRange();
10292  RefExpr = RefExpr->IgnoreParenImpCasts();
10293  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
10294  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
10295  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
10296      (S.getCurrentThisType().isNull() || !ME ||
10297       !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
10298       !isa<FieldDecl>(ME->getMemberDecl()))) {
10299    if (IsArrayExpr != NoArrayExpr) {
10300      S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
10301                                                         << ERange;
10302    } else {
10303      S.Diag(ELoc,
10304             AllowArraySection
10305                 ? diag::err_omp_expected_var_name_member_expr_or_array_item
10306                 : diag::err_omp_expected_var_name_member_expr)
10307          << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
10308    }
10309    return std::make_pair(nullptrfalse);
10310  }
10311  return std::make_pair(
10312      getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
10313}
10314
10315OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
10316                                          SourceLocation StartLoc,
10317                                          SourceLocation LParenLoc,
10318                                          SourceLocation EndLoc) {
10319  SmallVector<Expr *, 8Vars;
10320  SmallVector<Expr *, 8PrivateCopies;
10321  for (Expr *RefExpr : VarList) {
10322     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 10322, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP private clause.");
10323    SourceLocation ELoc;
10324    SourceRange ERange;
10325    Expr *SimpleRefExpr = RefExpr;
10326    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10327    if (Res.second) {
10328      // It will be analyzed later.
10329      Vars.push_back(RefExpr);
10330      PrivateCopies.push_back(nullptr);
10331    }
10332    ValueDecl *D = Res.first;
10333    if (!D)
10334      continue;
10335
10336    QualType Type = D->getType();
10337    auto *VD = dyn_cast<VarDecl>(D);
10338
10339    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10340    //  A variable that appears in a private clause must not have an incomplete
10341    //  type or a reference type.
10342    if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
10343      continue;
10344    Type = Type.getNonReferenceType();
10345
10346    // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
10347    // A variable that is privatized must not have a const-qualified type
10348    // unless it is of class type with a mutable member. This restriction does
10349    // not apply to the firstprivate clause.
10350    //
10351    // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
10352    // A variable that appears in a private clause must not have a
10353    // const-qualified type unless it is of class type with a mutable member.
10354    if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
10355      continue;
10356
10357    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10358    // in a Construct]
10359    //  Variables with the predetermined data-sharing attributes may not be
10360    //  listed in data-sharing attributes clauses, except for the cases
10361    //  listed below. For these exceptions only, listing a predetermined
10362    //  variable in a data-sharing attribute clause is allowed and overrides
10363    //  the variable's predetermined data-sharing attributes.
10364    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
10365    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
10366      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10367                                          << getOpenMPClauseName(OMPC_private);
10368      reportOriginalDsa(*thisDSAStack, D, DVar);
10369      continue;
10370    }
10371
10372    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
10373    // Variably modified types are not supported for tasks.
10374    if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
10375        isOpenMPTaskingDirective(CurrDir)) {
10376      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10377          << getOpenMPClauseName(OMPC_private) << Type
10378          << getOpenMPDirectiveName(CurrDir);
10379      bool IsDecl =
10380          !VD ||
10381          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10382      Diag(D->getLocation(),
10383           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10384          << D;
10385      continue;
10386    }
10387
10388    // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
10389    // A list item cannot appear in both a map clause and a data-sharing
10390    // attribute clause on the same construct
10391    if (isOpenMPTargetExecutionDirective(CurrDir)) {
10392      OpenMPClauseKind ConflictKind;
10393      if (DSAStack->checkMappableExprComponentListsForDecl(
10394              VD, /*CurrentRegionOnly=*/true,
10395              [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
10396                  OpenMPClauseKind WhereFoundClauseKind) -> bool {
10397                ConflictKind = WhereFoundClauseKind;
10398                return true;
10399              })) {
10400        Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
10401            << getOpenMPClauseName(OMPC_private)
10402            << getOpenMPClauseName(ConflictKind)
10403            << getOpenMPDirectiveName(CurrDir);
10404        reportOriginalDsa(*thisDSAStack, D, DVar);
10405        continue;
10406      }
10407    }
10408
10409    // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
10410    //  A variable of class type (or array thereof) that appears in a private
10411    //  clause requires an accessible, unambiguous default constructor for the
10412    //  class type.
10413    // Generate helper private variable and initialize it with the default
10414    // value. The address of the original variable is replaced by the address of
10415    // the new private variable in CodeGen. This new variable is not added to
10416    // IdResolver, so the code in the OpenMP region uses original variable for
10417    // proper diagnostics.
10418    Type = Type.getUnqualifiedType();
10419    VarDecl *VDPrivate =
10420        buildVarDecl(*this, ELoc, Type, D->getName(),
10421                     D->hasAttrs() ? &D->getAttrs() : nullptr,
10422                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
10423    ActOnUninitializedDecl(VDPrivate);
10424    if (VDPrivate->isInvalidDecl())
10425      continue;
10426    DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
10427        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
10428
10429    DeclRefExpr *Ref = nullptr;
10430    if (!VD && !CurContext->isDependentContext())
10431      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
10432    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
10433    Vars.push_back((VD || CurContext->isDependentContext())
10434                       ? RefExpr->IgnoreParens()
10435                       : Ref);
10436    PrivateCopies.push_back(VDPrivateRefExpr);
10437  }
10438
10439  if (Vars.empty())
10440    return nullptr;
10441
10442  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
10443                                  PrivateCopies);
10444}
10445
10446namespace {
10447class DiagsUninitializedSeveretyRAII {
10448private:
10449  DiagnosticsEngine &Diags;
10450  SourceLocation SavedLoc;
10451  bool IsIgnored = false;
10452
10453public:
10454  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &DiagsSourceLocation Loc,
10455                                 bool IsIgnored)
10456      : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
10457    if (!IsIgnored) {
10458      Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
10459                        /*Map*/ diag::Severity::Ignored, Loc);
10460    }
10461  }
10462  ~DiagsUninitializedSeveretyRAII() {
10463    if (!IsIgnored)
10464      Diags.popMappings(SavedLoc);
10465  }
10466};
10467}
10468
10469OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
10470                                               SourceLocation StartLoc,
10471                                               SourceLocation LParenLoc,
10472                                               SourceLocation EndLoc) {
10473  SmallVector<Expr *, 8Vars;
10474  SmallVector<Expr *, 8PrivateCopies;
10475  SmallVector<Expr *, 8Inits;
10476  SmallVector<Decl *, 4ExprCaptures;
10477  bool IsImplicitClause =
10478      StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
10479  SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
10480
10481  for (Expr *RefExpr : VarList) {
10482     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP firstprivate clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 10482, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
10483    SourceLocation ELoc;
10484    SourceRange ERange;
10485    Expr *SimpleRefExpr = RefExpr;
10486    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10487    if (Res.second) {
10488      // It will be analyzed later.
10489      Vars.push_back(RefExpr);
10490      PrivateCopies.push_back(nullptr);
10491      Inits.push_back(nullptr);
10492    }
10493    ValueDecl *D = Res.first;
10494    if (!D)
10495      continue;
10496
10497    ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
10498    QualType Type = D->getType();
10499    auto *VD = dyn_cast<VarDecl>(D);
10500
10501    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10502    //  A variable that appears in a private clause must not have an incomplete
10503    //  type or a reference type.
10504    if (RequireCompleteType(ELoc, Type,
10505                            diag::err_omp_firstprivate_incomplete_type))
10506      continue;
10507    Type = Type.getNonReferenceType();
10508
10509    // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
10510    //  A variable of class type (or array thereof) that appears in a private
10511    //  clause requires an accessible, unambiguous copy constructor for the
10512    //  class type.
10513    QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
10514
10515    // If an implicit firstprivate variable found it was checked already.
10516    DSAStackTy::DSAVarData TopDVar;
10517    if (!IsImplicitClause) {
10518      DSAStackTy::DSAVarData DVar =
10519          DSAStack->getTopDSA(D, /*FromParent=*/false);
10520      TopDVar = DVar;
10521      OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
10522      bool IsConstant = ElemType.isConstant(Context);
10523      // OpenMP [2.4.13, Data-sharing Attribute Clauses]
10524      //  A list item that specifies a given variable may not appear in more
10525      // than one clause on the same directive, except that a variable may be
10526      //  specified in both firstprivate and lastprivate clauses.
10527      // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
10528      // A list item may appear in a firstprivate or lastprivate clause but not
10529      // both.
10530      if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
10531          (isOpenMPDistributeDirective(CurrDir) ||
10532           DVar.CKind != OMPC_lastprivate) &&
10533          DVar.RefExpr) {
10534        Diag(ELoc, diag::err_omp_wrong_dsa)
10535            << getOpenMPClauseName(DVar.CKind)
10536            << getOpenMPClauseName(OMPC_firstprivate);
10537        reportOriginalDsa(*thisDSAStack, D, DVar);
10538        continue;
10539      }
10540
10541      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10542      // in a Construct]
10543      //  Variables with the predetermined data-sharing attributes may not be
10544      //  listed in data-sharing attributes clauses, except for the cases
10545      //  listed below. For these exceptions only, listing a predetermined
10546      //  variable in a data-sharing attribute clause is allowed and overrides
10547      //  the variable's predetermined data-sharing attributes.
10548      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10549      // in a Construct, C/C++, p.2]
10550      //  Variables with const-qualified type having no mutable member may be
10551      //  listed in a firstprivate clause, even if they are static data members.
10552      if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
10553          DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
10554        Diag(ELoc, diag::err_omp_wrong_dsa)
10555            << getOpenMPClauseName(DVar.CKind)
10556            << getOpenMPClauseName(OMPC_firstprivate);
10557        reportOriginalDsa(*thisDSAStack, D, DVar);
10558        continue;
10559      }
10560
10561      // OpenMP [2.9.3.4, Restrictions, p.2]
10562      //  A list item that is private within a parallel region must not appear
10563      //  in a firstprivate clause on a worksharing construct if any of the
10564      //  worksharing regions arising from the worksharing construct ever bind
10565      //  to any of the parallel regions arising from the parallel construct.
10566      // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10567      // A list item that is private within a teams region must not appear in a
10568      // firstprivate clause on a distribute construct if any of the distribute
10569      // regions arising from the distribute construct ever bind to any of the
10570      // teams regions arising from the teams construct.
10571      // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10572      // A list item that appears in a reduction clause of a teams construct
10573      // must not appear in a firstprivate clause on a distribute construct if
10574      // any of the distribute regions arising from the distribute construct
10575      // ever bind to any of the teams regions arising from the teams construct.
10576      if ((isOpenMPWorksharingDirective(CurrDir) ||
10577           isOpenMPDistributeDirective(CurrDir)) &&
10578          !isOpenMPParallelDirective(CurrDir) &&
10579          !isOpenMPTeamsDirective(CurrDir)) {
10580        DVar = DSAStack->getImplicitDSA(D, true);
10581        if (DVar.CKind != OMPC_shared &&
10582            (isOpenMPParallelDirective(DVar.DKind) ||
10583             isOpenMPTeamsDirective(DVar.DKind) ||
10584             DVar.DKind == OMPD_unknown)) {
10585          Diag(ELoc, diag::err_omp_required_access)
10586              << getOpenMPClauseName(OMPC_firstprivate)
10587              << getOpenMPClauseName(OMPC_shared);
10588          reportOriginalDsa(*thisDSAStack, D, DVar);
10589          continue;
10590        }
10591      }
10592      // OpenMP [2.9.3.4, Restrictions, p.3]
10593      //  A list item that appears in a reduction clause of a parallel construct
10594      //  must not appear in a firstprivate clause on a worksharing or task
10595      //  construct if any of the worksharing or task regions arising from the
10596      //  worksharing or task construct ever bind to any of the parallel regions
10597      //  arising from the parallel construct.
10598      // OpenMP [2.9.3.4, Restrictions, p.4]
10599      //  A list item that appears in a reduction clause in worksharing
10600      //  construct must not appear in a firstprivate clause in a task construct
10601      //  encountered during execution of any of the worksharing regions arising
10602      //  from the worksharing construct.
10603      if (isOpenMPTaskingDirective(CurrDir)) {
10604        DVar = DSAStack->hasInnermostDSA(
10605            D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
10606            [](OpenMPDirectiveKind K) {
10607              return isOpenMPParallelDirective(K) ||
10608                     isOpenMPWorksharingDirective(K) ||
10609                     isOpenMPTeamsDirective(K);
10610            },
10611            /*FromParent=*/true);
10612        if (DVar.CKind == OMPC_reduction &&
10613            (isOpenMPParallelDirective(DVar.DKind) ||
10614             isOpenMPWorksharingDirective(DVar.DKind) ||
10615             isOpenMPTeamsDirective(DVar.DKind))) {
10616          Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
10617              << getOpenMPDirectiveName(DVar.DKind);
10618          reportOriginalDsa(*thisDSAStack, D, DVar);
10619          continue;
10620        }
10621      }
10622
10623      // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
10624      // A list item cannot appear in both a map clause and a data-sharing
10625      // attribute clause on the same construct
10626      if (isOpenMPTargetExecutionDirective(CurrDir)) {
10627        OpenMPClauseKind ConflictKind;
10628        if (DSAStack->checkMappableExprComponentListsForDecl(
10629                VD, /*CurrentRegionOnly=*/true,
10630                [&ConflictKind](
10631                    OMPClauseMappableExprCommon::MappableExprComponentListRef,
10632                    OpenMPClauseKind WhereFoundClauseKind) {
10633                  ConflictKind = WhereFoundClauseKind;
10634                  return true;
10635                })) {
10636          Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
10637              << getOpenMPClauseName(OMPC_firstprivate)
10638              << getOpenMPClauseName(ConflictKind)
10639              << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
10640          reportOriginalDsa(*thisDSAStack, D, DVar);
10641          continue;
10642        }
10643      }
10644    }
10645
10646    // Variably modified types are not supported for tasks.
10647    if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
10648        isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
10649      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10650          << getOpenMPClauseName(OMPC_firstprivate) << Type
10651          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
10652      bool IsDecl =
10653          !VD ||
10654          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10655      Diag(D->getLocation(),
10656           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10657          << D;
10658      continue;
10659    }
10660
10661    Type = Type.getUnqualifiedType();
10662    VarDecl *VDPrivate =
10663        buildVarDecl(*this, ELoc, Type, D->getName(),
10664                     D->hasAttrs() ? &D->getAttrs() : nullptr,
10665                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
10666    // Generate helper private variable and initialize it with the value of the
10667    // original variable. The address of the original variable is replaced by
10668    // the address of the new private variable in the CodeGen. This new variable
10669    // is not added to IdResolver, so the code in the OpenMP region uses
10670    // original variable for proper diagnostics and variable capturing.
10671    Expr *VDInitRefExpr = nullptr;
10672    // For arrays generate initializer for single element and replace it by the
10673    // original array element in CodeGen.
10674    if (Type->isArrayType()) {
10675      VarDecl *VDInit =
10676          buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
10677      VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
10678      Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
10679      ElemType = ElemType.getUnqualifiedType();
10680      VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
10681                                         ".firstprivate.temp");
10682      InitializedEntity Entity =
10683          InitializedEntity::InitializeVariable(VDInitTemp);
10684      InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
10685
10686      InitializationSequence InitSeq(*this, Entity, Kind, Init);
10687      ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
10688      if (Result.isInvalid())
10689        VDPrivate->setInvalidDecl();
10690      else
10691        VDPrivate->setInit(Result.getAs<Expr>());
10692      // Remove temp variable declaration.
10693      Context.Deallocate(VDInitTemp);
10694    } else {
10695      VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
10696                                     ".firstprivate.temp");
10697      VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
10698                                       RefExpr->getExprLoc());
10699      AddInitializerToDecl(VDPrivate,
10700                           DefaultLvalueConversion(VDInitRefExpr).get(),
10701                           /*DirectInit=*/false);
10702    }
10703    if (VDPrivate->isInvalidDecl()) {
10704      if (IsImplicitClause) {
10705        Diag(RefExpr->getExprLoc(),
10706             diag::note_omp_task_predetermined_firstprivate_here);
10707      }
10708      continue;
10709    }
10710    CurContext->addDecl(VDPrivate);
10711    DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
10712        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
10713        RefExpr->getExprLoc());
10714    DeclRefExpr *Ref = nullptr;
10715    if (!VD && !CurContext->isDependentContext()) {
10716      if (TopDVar.CKind == OMPC_lastprivate) {
10717        Ref = TopDVar.PrivateCopy;
10718      } else {
10719        Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10720        if (!isOpenMPCapturedDecl(D))
10721          ExprCaptures.push_back(Ref->getDecl());
10722      }
10723    }
10724    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
10725    Vars.push_back((VD || CurContext->isDependentContext())
10726                       ? RefExpr->IgnoreParens()
10727                       : Ref);
10728    PrivateCopies.push_back(VDPrivateRefExpr);
10729    Inits.push_back(VDInitRefExpr);
10730  }
10731
10732  if (Vars.empty())
10733    return nullptr;
10734
10735  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10736                                       Vars, PrivateCopies, Inits,
10737                                       buildPreInits(Context, ExprCaptures));
10738}
10739
10740OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
10741                                              SourceLocation StartLoc,
10742                                              SourceLocation LParenLoc,
10743                                              SourceLocation EndLoc) {
10744  SmallVector<Expr *, 8Vars;
10745  SmallVector<Expr *, 8SrcExprs;
10746  SmallVector<Expr *, 8DstExprs;
10747  SmallVector<Expr *, 8AssignmentOps;
10748  SmallVector<Decl *, 4ExprCaptures;
10749  SmallVector<Expr *, 4ExprPostUpdates;
10750  for (Expr *RefExpr : VarList) {
10751     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 10751, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
10752    SourceLocation ELoc;
10753    SourceRange ERange;
10754    Expr *SimpleRefExpr = RefExpr;
10755    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10756    if (Res.second) {
10757      // It will be analyzed later.
10758      Vars.push_back(RefExpr);
10759      SrcExprs.push_back(nullptr);
10760      DstExprs.push_back(nullptr);
10761      AssignmentOps.push_back(nullptr);
10762    }
10763    ValueDecl *D = Res.first;
10764    if (!D)
10765      continue;
10766
10767    QualType Type = D->getType();
10768    auto *VD = dyn_cast<VarDecl>(D);
10769
10770    // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
10771    //  A variable that appears in a lastprivate clause must not have an
10772    //  incomplete type or a reference type.
10773    if (RequireCompleteType(ELoc, Type,
10774                            diag::err_omp_lastprivate_incomplete_type))
10775      continue;
10776    Type = Type.getNonReferenceType();
10777
10778    // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
10779    // A variable that is privatized must not have a const-qualified type
10780    // unless it is of class type with a mutable member. This restriction does
10781    // not apply to the firstprivate clause.
10782    //
10783    // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
10784    // A variable that appears in a lastprivate clause must not have a
10785    // const-qualified type unless it is of class type with a mutable member.
10786    if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
10787      continue;
10788
10789    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
10790    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10791    // in a Construct]
10792    //  Variables with the predetermined data-sharing attributes may not be
10793    //  listed in data-sharing attributes clauses, except for the cases
10794    //  listed below.
10795    // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
10796    // A list item may appear in a firstprivate or lastprivate clause but not
10797    // both.
10798    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
10799    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
10800        (isOpenMPDistributeDirective(CurrDir) ||
10801         DVar.CKind != OMPC_firstprivate) &&
10802        (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
10803      Diag(ELoc, diag::err_omp_wrong_dsa)
10804          << getOpenMPClauseName(DVar.CKind)
10805          << getOpenMPClauseName(OMPC_lastprivate);
10806      reportOriginalDsa(*thisDSAStack, D, DVar);
10807      continue;
10808    }
10809
10810    // OpenMP [2.14.3.5, Restrictions, p.2]
10811    // A list item that is private within a parallel region, or that appears in
10812    // the reduction clause of a parallel construct, must not appear in a
10813    // lastprivate clause on a worksharing construct if any of the corresponding
10814    // worksharing regions ever binds to any of the corresponding parallel
10815    // regions.
10816    DSAStackTy::DSAVarData TopDVar = DVar;
10817    if (isOpenMPWorksharingDirective(CurrDir) &&
10818        !isOpenMPParallelDirective(CurrDir) &&
10819        !isOpenMPTeamsDirective(CurrDir)) {
10820      DVar = DSAStack->getImplicitDSA(D, true);
10821      if (DVar.CKind != OMPC_shared) {
10822        Diag(ELoc, diag::err_omp_required_access)
10823            << getOpenMPClauseName(OMPC_lastprivate)
10824            << getOpenMPClauseName(OMPC_shared);
10825        reportOriginalDsa(*thisDSAStack, D, DVar);
10826        continue;
10827      }
10828    }
10829
10830    // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
10831    //  A variable of class type (or array thereof) that appears in a
10832    //  lastprivate clause requires an accessible, unambiguous default
10833    //  constructor for the class type, unless the list item is also specified
10834    //  in a firstprivate clause.
10835    //  A variable of class type (or array thereof) that appears in a
10836    //  lastprivate clause requires an accessible, unambiguous copy assignment
10837    //  operator for the class type.
10838    Type = Context.getBaseElementType(Type).getNonReferenceType();
10839    VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
10840                                  Type.getUnqualifiedType(), ".lastprivate.src",
10841                                  D->hasAttrs() ? &D->getAttrs() : nullptr);
10842    DeclRefExpr *PseudoSrcExpr =
10843        buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
10844    VarDecl *DstVD =
10845        buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
10846                     D->hasAttrs() ? &D->getAttrs() : nullptr);
10847    DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
10848    // For arrays generate assignment operation for single element and replace
10849    // it by the original array element in CodeGen.
10850    ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
10851                                         PseudoDstExpr, PseudoSrcExpr);
10852    if (AssignmentOp.isInvalid())
10853      continue;
10854    AssignmentOp =
10855        ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
10856    if (AssignmentOp.isInvalid())
10857      continue;
10858
10859    DeclRefExpr *Ref = nullptr;
10860    if (!VD && !CurContext->isDependentContext()) {
10861      if (TopDVar.CKind == OMPC_firstprivate) {
10862        Ref = TopDVar.PrivateCopy;
10863      } else {
10864        Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
10865        if (!isOpenMPCapturedDecl(D))
10866          ExprCaptures.push_back(Ref->getDecl());
10867      }
10868      if (TopDVar.CKind == OMPC_firstprivate ||
10869          (!isOpenMPCapturedDecl(D) &&
10870           Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
10871        ExprResult RefRes = DefaultLvalueConversion(Ref);
10872        if (!RefRes.isUsable())
10873          continue;
10874        ExprResult PostUpdateRes =
10875            BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10876                       RefRes.get());
10877        if (!PostUpdateRes.isUsable())
10878          continue;
10879        ExprPostUpdates.push_back(
10880            IgnoredValueConversions(PostUpdateRes.get()).get());
10881      }
10882    }
10883    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
10884    Vars.push_back((VD || CurContext->isDependentContext())
10885                       ? RefExpr->IgnoreParens()
10886                       : Ref);
10887    SrcExprs.push_back(PseudoSrcExpr);
10888    DstExprs.push_back(PseudoDstExpr);
10889    AssignmentOps.push_back(AssignmentOp.get());
10890  }
10891
10892  if (Vars.empty())
10893    return nullptr;
10894
10895  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10896                                      Vars, SrcExprs, DstExprs, AssignmentOps,
10897                                      buildPreInits(Context, ExprCaptures),
10898                                      buildPostUpdate(*this, ExprPostUpdates));
10899}
10900
10901OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
10902                                         SourceLocation StartLoc,
10903                                         SourceLocation LParenLoc,
10904                                         SourceLocation EndLoc) {
10905  SmallVector<Expr *, 8Vars;
10906  for (Expr *RefExpr : VarList) {
10907     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 10907, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
10908    SourceLocation ELoc;
10909    SourceRange ERange;
10910    Expr *SimpleRefExpr = RefExpr;
10911    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10912    if (Res.second) {
10913      // It will be analyzed later.
10914      Vars.push_back(RefExpr);
10915    }
10916    ValueDecl *D = Res.first;
10917    if (!D)
10918      continue;
10919
10920    auto *VD = dyn_cast<VarDecl>(D);
10921    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10922    // in a Construct]
10923    //  Variables with the predetermined data-sharing attributes may not be
10924    //  listed in data-sharing attributes clauses, except for the cases
10925    //  listed below. For these exceptions only, listing a predetermined
10926    //  variable in a data-sharing attribute clause is allowed and overrides
10927    //  the variable's predetermined data-sharing attributes.
10928    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
10929    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
10930        DVar.RefExpr) {
10931      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10932                                          << getOpenMPClauseName(OMPC_shared);
10933      reportOriginalDsa(*thisDSAStack, D, DVar);
10934      continue;
10935    }
10936
10937    DeclRefExpr *Ref = nullptr;
10938    if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
10939      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10940    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
10941    Vars.push_back((VD || !Ref || CurContext->isDependentContext())
10942                       ? RefExpr->IgnoreParens()
10943                       : Ref);
10944  }
10945
10946  if (Vars.empty())
10947    return nullptr;
10948
10949  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
10950}
10951
10952namespace {
10953class DSARefChecker : public StmtVisitor<DSARefCheckerbool> {
10954  DSAStackTy *Stack;
10955
10956public:
10957  bool VisitDeclRefExpr(DeclRefExpr *E) {
10958    if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
10959      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
10960      if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
10961        return false;
10962      if (DVar.CKind != OMPC_unknown)
10963        return true;
10964      DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
10965          VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
10966          /*FromParent=*/true);
10967      return DVarPrivate.CKind != OMPC_unknown;
10968    }
10969    return false;
10970  }
10971  bool VisitStmt(Stmt *S) {
10972    for (Stmt *Child : S->children()) {
10973      if (Child && Visit(Child))
10974        return true;
10975    }
10976    return false;
10977  }
10978  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
10979};
10980// namespace
10981
10982namespace {
10983// Transform MemberExpression for specified FieldDecl of current class to
10984// DeclRefExpr to specified OMPCapturedExprDecl.
10985class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
10986  typedef TreeTransform<TransformExprToCapturesBaseTransform;
10987  ValueDecl *Field = nullptr;
10988  DeclRefExpr *CapturedExpr = nullptr;
10989
10990public:
10991  TransformExprToCaptures(Sema &SemaRefValueDecl *FieldDecl)
10992      : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
10993
10994  ExprResult TransformMemberExpr(MemberExpr *E) {
10995    if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
10996        E->getMemberDecl() == Field) {
10997      CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
10998      return CapturedExpr;
10999    }
11000    return BaseTransform::TransformMemberExpr(E);
11001  }
11002  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
11003};
11004// namespace
11005
11006template <typename T, typename U>
11007static T filterLookupForUDReductionAndMapper(
11008    SmallVectorImpl<U> &Lookupsconst llvm::function_ref<T(ValueDecl *)> Gen) {
11009  for (U &Set : Lookups) {
11010    for (auto *D : Set) {
11011      if (T Res = Gen(cast<ValueDecl>(D)))
11012        return Res;
11013    }
11014  }
11015  return T();
11016}
11017
11018static NamedDecl *findAcceptableDecl(Sema &SemaRefNamedDecl *D) {
11019   (0) . __assert_fail ("!LookupResult..isVisible(SemaRef, D) && \"not in slow case\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 11019, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
11020
11021  for (auto RD : D->redecls()) {
11022    // Don't bother with extra checks if we already know this one isn't visible.
11023    if (RD == D)
11024      continue;
11025
11026    auto ND = cast<NamedDecl>(RD);
11027    if (LookupResult::isVisible(SemaRef, ND))
11028      return ND;
11029  }
11030
11031  return nullptr;
11032}
11033
11034static void
11035argumentDependentLookup(Sema &SemaRefconst DeclarationNameInfo &Id,
11036                        SourceLocation LocQualType Ty,
11037                        SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
11038  // Find all of the associated namespaces and classes based on the
11039  // arguments we have.
11040  Sema::AssociatedNamespaceSet AssociatedNamespaces;
11041  Sema::AssociatedClassSet AssociatedClasses;
11042  OpaqueValueExpr OVE(LocTyVK_LValue);
11043  SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
11044                                             AssociatedClasses);
11045
11046  // C++ [basic.lookup.argdep]p3:
11047  //   Let X be the lookup set produced by unqualified lookup (3.4.1)
11048  //   and let Y be the lookup set produced by argument dependent
11049  //   lookup (defined as follows). If X contains [...] then Y is
11050  //   empty. Otherwise Y is the set of declarations found in the
11051  //   namespaces associated with the argument types as described
11052  //   below. The set of declarations found by the lookup of the name
11053  //   is the union of X and Y.
11054  //
11055  // Here, we compute Y and add its members to the overloaded
11056  // candidate set.
11057  for (auto *NS : AssociatedNamespaces) {
11058    //   When considering an associated namespace, the lookup is the
11059    //   same as the lookup performed when the associated namespace is
11060    //   used as a qualifier (3.4.3.2) except that:
11061    //
11062    //     -- Any using-directives in the associated namespace are
11063    //        ignored.
11064    //
11065    //     -- Any namespace-scope friend functions declared in
11066    //        associated classes are visible within their respective
11067    //        namespaces even if they are not visible during an ordinary
11068    //        lookup (11.4).
11069    DeclContext::lookup_result R = NS->lookup(Id.getName());
11070    for (auto *D : R) {
11071      auto *Underlying = D;
11072      if (auto *USD = dyn_cast<UsingShadowDecl>(D))
11073        Underlying = USD->getTargetDecl();
11074
11075      if (!isa<OMPDeclareReductionDecl>(Underlying) &&
11076          !isa<OMPDeclareMapperDecl>(Underlying))
11077        continue;
11078
11079      if (!SemaRef.isVisible(D)) {
11080        D = findAcceptableDecl(SemaRef, D);
11081        if (!D)
11082          continue;
11083        if (auto *USD = dyn_cast<UsingShadowDecl>(D))
11084          Underlying = USD->getTargetDecl();
11085      }
11086      Lookups.emplace_back();
11087      Lookups.back().addDecl(Underlying);
11088    }
11089  }
11090}
11091
11092static ExprResult
11093buildDeclareReductionRef(Sema &SemaRefSourceLocation LocSourceRange Range,
11094                         Scope *SCXXScopeSpec &ReductionIdScopeSpec,
11095                         const DeclarationNameInfo &ReductionIdQualType Ty,
11096                         CXXCastPath &BasePathExpr *UnresolvedReduction) {
11097  if (ReductionIdScopeSpec.isInvalid())
11098    return ExprError();
11099  SmallVector<UnresolvedSet<8>, 4Lookups;
11100  if (S) {
11101    LookupResult Lookup(SemaRefReductionIdSema::LookupOMPReductionName);
11102    Lookup.suppressDiagnostics();
11103    while (S && SemaRef.LookupParsedName(LookupS, &ReductionIdScopeSpec)) {
11104      NamedDecl *D = Lookup.getRepresentativeDecl();
11105      do {
11106        S = S->getParent();
11107      } while (S && !S->isDeclScope(D));
11108      if (S)
11109        S = S->getParent();
11110      Lookups.emplace_back();
11111      Lookups.back().append(Lookup.begin(), Lookup.end());
11112      Lookup.clear();
11113    }
11114  } else if (auto *ULE =
11115                 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
11116    Lookups.push_back(UnresolvedSet<8>());
11117    Decl *PrevD = nullptr;
11118    for (NamedDecl *D : ULE->decls()) {
11119      if (D == PrevD)
11120        Lookups.push_back(UnresolvedSet<8>());
11121      else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
11122        Lookups.back().addDecl(DRD);
11123      PrevD = D;
11124    }
11125  }
11126  if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
11127      Ty->isInstantiationDependentType() ||
11128      Ty->containsUnexpandedParameterPack() ||
11129      filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
11130        return !D->isInvalidDecl() &&
11131               (D->getType()->isDependentType() ||
11132                D->getType()->isInstantiationDependentType() ||
11133                D->getType()->containsUnexpandedParameterPack());
11134      })) {
11135    UnresolvedSet<8ResSet;
11136    for (const UnresolvedSet<8> &Set : Lookups) {
11137      if (Set.empty())
11138        continue;
11139      ResSet.append(Set.begin(), Set.end());
11140      // The last item marks the end of all declarations at the specified scope.
11141      ResSet.addDecl(Set[Set.size() - 1]);
11142    }
11143    return UnresolvedLookupExpr::Create(
11144        SemaRef.Context/*NamingClass=*/nullptr,
11145        ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
11146        /*ADL=*/true/*Overloaded=*/trueResSet.begin(), ResSet.end());
11147  }
11148  // Lookup inside the classes.
11149  // C++ [over.match.oper]p3:
11150  //   For a unary operator @ with an operand of a type whose
11151  //   cv-unqualified version is T1, and for a binary operator @ with
11152  //   a left operand of a type whose cv-unqualified version is T1 and
11153  //   a right operand of a type whose cv-unqualified version is T2,
11154  //   three sets of candidate functions, designated member
11155  //   candidates, non-member candidates and built-in candidates, are
11156  //   constructed as follows:
11157  //     -- If T1 is a complete class type or a class currently being
11158  //        defined, the set of member candidates is the result of the
11159  //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
11160  //        the set of member candidates is empty.
11161  LookupResult Lookup(SemaRefReductionIdSema::LookupOMPReductionName);
11162  Lookup.suppressDiagnostics();
11163  if (const auto *TyRec = Ty->getAs<RecordType>()) {
11164    // Complete the type if it can be completed.
11165    // If the type is neither complete nor being defined, bail out now.
11166    if (SemaRef.isCompleteType(LocTy) || TyRec->isBeingDefined() ||
11167        TyRec->getDecl()->getDefinition()) {
11168      Lookup.clear();
11169      SemaRef.LookupQualifiedName(LookupTyRec->getDecl());
11170      if (Lookup.empty()) {
11171        Lookups.emplace_back();
11172        Lookups.back().append(Lookup.begin(), Lookup.end());
11173      }
11174    }
11175  }
11176  // Perform ADL.
11177  if (SemaRef.getLangOpts().CPlusPlus) {
11178    argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
11179    if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
11180            Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
11181              if (!D->isInvalidDecl() &&
11182                  SemaRef.Context.hasSameType(D->getType(), Ty))
11183                return D;
11184              return nullptr;
11185            }))
11186      return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
11187                                      VK_LValue, Loc);
11188    if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
11189            Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
11190              if (!D->isInvalidDecl() &&
11191                  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
11192                  !Ty.isMoreQualifiedThan(D->getType()))
11193                return D;
11194              return nullptr;
11195            })) {
11196      CXXBasePaths Paths(/*FindAmbiguities=*/true/*RecordPaths=*/true,
11197                         /*DetectVirtual=*/false);
11198      if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
11199        if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
11200                VD->getType().getUnqualifiedType()))) {
11201          if (SemaRef.CheckBaseClassAccess(
11202                  Loc, VD->getType(), Ty, Paths.front(),
11203                  /*DiagID=*/0) != Sema::AR_inaccessible) {
11204            SemaRef.BuildBasePathArray(PathsBasePath);
11205            return SemaRef.BuildDeclRefExpr(
11206                VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
11207          }
11208        }
11209      }
11210    }
11211  }
11212  if (ReductionIdScopeSpec.isSet()) {
11213    SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
11214    return ExprError();
11215  }
11216  return ExprEmpty();
11217}
11218
11219namespace {
11220/// Data for the reduction-based clauses.
11221struct ReductionData {
11222  /// List of original reduction items.
11223  SmallVector<Expr *, 8Vars;
11224  /// List of private copies of the reduction items.
11225  SmallVector<Expr *, 8Privates;
11226  /// LHS expressions for the reduction_op expressions.
11227  SmallVector<Expr *, 8LHSs;
11228  /// RHS expressions for the reduction_op expressions.
11229  SmallVector<Expr *, 8RHSs;
11230  /// Reduction operation expression.
11231  SmallVector<Expr *, 8ReductionOps;
11232  /// Taskgroup descriptors for the corresponding reduction items in
11233  /// in_reduction clauses.
11234  SmallVector<Expr *, 8TaskgroupDescriptors;
11235  /// List of captures for clause.
11236  SmallVector<Decl *, 4ExprCaptures;
11237  /// List of postupdate expressions.
11238  SmallVector<Expr *, 4ExprPostUpdates;
11239  ReductionData() = delete;
11240  /// Reserves required memory for the reduction data.
11241  ReductionData(unsigned Size) {
11242    Vars.reserve(Size);
11243    Privates.reserve(Size);
11244    LHSs.reserve(Size);
11245    RHSs.reserve(Size);
11246    ReductionOps.reserve(Size);
11247    TaskgroupDescriptors.reserve(Size);
11248    ExprCaptures.reserve(Size);
11249    ExprPostUpdates.reserve(Size);
11250  }
11251  /// Stores reduction item and reduction operation only (required for dependent
11252  /// reduction item).
11253  void push(Expr *ItemExpr *ReductionOp) {
11254    Vars.emplace_back(Item);
11255    Privates.emplace_back(nullptr);
11256    LHSs.emplace_back(nullptr);
11257    RHSs.emplace_back(nullptr);
11258    ReductionOps.emplace_back(ReductionOp);
11259    TaskgroupDescriptors.emplace_back(nullptr);
11260  }
11261  /// Stores reduction data.
11262  void push(Expr *ItemExpr *PrivateExpr *LHSExpr *RHSExpr *ReductionOp,
11263            Expr *TaskgroupDescriptor) {
11264    Vars.emplace_back(Item);
11265    Privates.emplace_back(Private);
11266    LHSs.emplace_back(LHS);
11267    RHSs.emplace_back(RHS);
11268    ReductionOps.emplace_back(ReductionOp);
11269    TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
11270  }
11271};
11272// namespace
11273
11274static bool checkOMPArraySectionConstantForReduction(
11275    ASTContext &Contextconst OMPArraySectionExpr *OASEbool &SingleElement,
11276    SmallVectorImpl<llvm::APSInt> &ArraySizes) {
11277  const Expr *Length = OASE->getLength();
11278  if (Length == nullptr) {
11279    // For array sections of the form [1:] or [:], we would need to analyze
11280    // the lower bound...
11281    if (OASE->getColonLoc().isValid())
11282      return false;
11283
11284    // This is an array subscript which has implicit length 1!
11285    SingleElement = true;
11286    ArraySizes.push_back(llvm::APSInt::get(1));
11287  } else {
11288    Expr::EvalResult Result;
11289    if (!Length->EvaluateAsInt(ResultContext))
11290      return false;
11291
11292    llvm::APSInt ConstantLengthValue = Result.Val.getInt();
11293    SingleElement = (ConstantLengthValue.getSExtValue() == 1);
11294    ArraySizes.push_back(ConstantLengthValue);
11295  }
11296
11297  // Get the base of this array section and walk up from there.
11298  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
11299
11300  // We require length = 1 for all array sections except the right-most to
11301  // guarantee that the memory region is contiguous and has no holes in it.
11302  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
11303    Length = TempOASE->getLength();
11304    if (Length == nullptr) {
11305      // For array sections of the form [1:] or [:], we would need to analyze
11306      // the lower bound...
11307      if (OASE->getColonLoc().isValid())
11308        return false;
11309
11310      // This is an array subscript which has implicit length 1!
11311      ArraySizes.push_back(llvm::APSInt::get(1));
11312    } else {
11313      Expr::EvalResult Result;
11314      if (!Length->EvaluateAsInt(Result, Context))
11315        return false;
11316
11317      llvm::APSInt ConstantLengthValue = Result.Val.getInt();
11318      if (ConstantLengthValue.getSExtValue() != 1)
11319        return false;
11320
11321      ArraySizes.push_back(ConstantLengthValue);
11322    }
11323    Base = TempOASE->getBase()->IgnoreParenImpCasts();
11324  }
11325
11326  // If we have a single element, we don't need to add the implicit lengths.
11327  if (!SingleElement) {
11328    while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
11329      // Has implicit length 1!
11330      ArraySizes.push_back(llvm::APSInt::get(1));
11331      Base = TempASE->getBase()->IgnoreParenImpCasts();
11332    }
11333  }
11334
11335  // This array section can be privatized as a single value or as a constant
11336  // sized array.
11337  return true;
11338}
11339
11340static bool actOnOMPReductionKindClause(
11341    Sema &SDSAStackTy *StackOpenMPClauseKind ClauseKind,
11342    ArrayRef<Expr *> VarListSourceLocation StartLocSourceLocation LParenLoc,
11343    SourceLocation ColonLocSourceLocation EndLoc,
11344    CXXScopeSpec &ReductionIdScopeSpecconst DeclarationNameInfo &ReductionId,
11345    ArrayRef<Expr *> UnresolvedReductionsReductionData &RD) {
11346  DeclarationName DN = ReductionId.getName();
11347  OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
11348  BinaryOperatorKind BOK = BO_Comma;
11349
11350  ASTContext &Context = S.Context;
11351  // OpenMP [2.14.3.6, reduction clause]
11352  // C
11353  // reduction-identifier is either an identifier or one of the following
11354  // operators: +, -, *,  &, |, ^, && and ||
11355  // C++
11356  // reduction-identifier is either an id-expression or one of the following
11357  // operators: +, -, *, &, |, ^, && and ||
11358  switch (OOK) {
11359  case OO_Plus:
11360  case OO_Minus:
11361    BOK = BO_Add;
11362    break;
11363  case OO_Star:
11364    BOK = BO_Mul;
11365    break;
11366  case OO_Amp:
11367    BOK = BO_And;
11368    break;
11369  case OO_Pipe:
11370    BOK = BO_Or;
11371    break;
11372  case OO_Caret:
11373    BOK = BO_Xor;
11374    break;
11375  case OO_AmpAmp:
11376    BOK = BO_LAnd;
11377    break;
11378  case OO_PipePipe:
11379    BOK = BO_LOr;
11380    break;
11381  case OO_New:
11382  case OO_Delete:
11383  case OO_Array_New:
11384  case OO_Array_Delete:
11385  case OO_Slash:
11386  case OO_Percent:
11387  case OO_Tilde:
11388  case OO_Exclaim:
11389  case OO_Equal:
11390  case OO_Less:
11391  case OO_Greater:
11392  case OO_LessEqual:
11393  case OO_GreaterEqual:
11394  case OO_PlusEqual:
11395  case OO_MinusEqual:
11396  case OO_StarEqual:
11397  case OO_SlashEqual:
11398  case OO_PercentEqual:
11399  case OO_CaretEqual:
11400  case OO_AmpEqual:
11401  case OO_PipeEqual:
11402  case OO_LessLess:
11403  case OO_GreaterGreater:
11404  case OO_LessLessEqual:
11405  case OO_GreaterGreaterEqual:
11406  case OO_EqualEqual:
11407  case OO_ExclaimEqual:
11408  case OO_Spaceship:
11409  case OO_PlusPlus:
11410  case OO_MinusMinus:
11411  case OO_Comma:
11412  case OO_ArrowStar:
11413  case OO_Arrow:
11414  case OO_Call:
11415  case OO_Subscript:
11416  case OO_Conditional:
11417  case OO_Coawait:
11418  case NUM_OVERLOADED_OPERATORS:
11419    llvm_unreachable("Unexpected reduction identifier");
11420  case OO_None:
11421    if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
11422      if (II->isStr("max"))
11423        BOK = BO_GT;
11424      else if (II->isStr("min"))
11425        BOK = BO_LT;
11426    }
11427    break;
11428  }
11429  SourceRange ReductionIdRange;
11430  if (ReductionIdScopeSpec.isValid())
11431    ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
11432  else
11433    ReductionIdRange.setBegin(ReductionId.getBeginLoc());
11434  ReductionIdRange.setEnd(ReductionId.getEndLoc());
11435
11436  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
11437  bool FirstIter = true;
11438  for (Expr *RefExpr : VarList) {
11439     (0) . __assert_fail ("RefExpr && \"nullptr expr in OpenMP reduction clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 11439, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
11440    // OpenMP [2.1, C/C++]
11441    //  A list item is a variable or array section, subject to the restrictions
11442    //  specified in Section 2.4 on page 42 and in each of the sections
11443    // describing clauses and directives for which a list appears.
11444    // OpenMP  [2.14.3.3, Restrictions, p.1]
11445    //  A variable that is part of another variable (as an array or
11446    //  structure element) cannot appear in a private clause.
11447    if (!FirstIter && IR != ER)
11448      ++IR;
11449    FirstIter = false;
11450    SourceLocation ELoc;
11451    SourceRange ERange;
11452    Expr *SimpleRefExpr = RefExpr;
11453    auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
11454                              /*AllowArraySection=*/true);
11455    if (Res.second) {
11456      // Try to find 'declare reduction' corresponding construct before using
11457      // builtin/overloaded operators.
11458      QualType Type = Context.DependentTy;
11459      CXXCastPath BasePath;
11460      ExprResult DeclareReductionRef = buildDeclareReductionRef(
11461          S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
11462          ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
11463      Expr *ReductionOp = nullptr;
11464      if (S.CurContext->isDependentContext() &&
11465          (DeclareReductionRef.isUnset() ||
11466           isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
11467        ReductionOp = DeclareReductionRef.get();
11468      // It will be analyzed later.
11469      RD.push(RefExpr, ReductionOp);
11470    }
11471    ValueDecl *D = Res.first;
11472    if (!D)
11473      continue;
11474
11475    Expr *TaskgroupDescriptor = nullptr;
11476    QualType Type;
11477    auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
11478    auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
11479    if (ASE) {
11480      Type = ASE->getType().getNonReferenceType();
11481    } else if (OASE) {
11482      QualType BaseType =
11483          OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
11484      if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
11485        Type = ATy->getElementType();
11486      else
11487        Type = BaseType->getPointeeType();
11488      Type = Type.getNonReferenceType();
11489    } else {
11490      Type = Context.getBaseElementType(D->getType().getNonReferenceType());
11491    }
11492    auto *VD = dyn_cast<VarDecl>(D);
11493
11494    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
11495    //  A variable that appears in a private clause must not have an incomplete
11496    //  type or a reference type.
11497    if (S.RequireCompleteType(ELoc, D->getType(),
11498                              diag::err_omp_reduction_incomplete_type))
11499      continue;
11500    // OpenMP [2.14.3.6, reduction clause, Restrictions]
11501    // A list item that appears in a reduction clause must not be
11502    // const-qualified.
11503    if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
11504                                  /*AcceptIfMutable*/ false, ASE || OASE))
11505      continue;
11506
11507    OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
11508    // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
11509    //  If a list-item is a reference type then it must bind to the same object
11510    //  for all threads of the team.
11511    if (!ASE && !OASE) {
11512      if (VD) {
11513        VarDecl *VDDef = VD->getDefinition();
11514        if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
11515          DSARefChecker Check(Stack);
11516          if (Check.Visit(VDDef->getInit())) {
11517            S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
11518                << getOpenMPClauseName(ClauseKind) << ERange;
11519            S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
11520            continue;
11521          }
11522        }
11523      }
11524
11525      // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
11526      // in a Construct]
11527      //  Variables with the predetermined data-sharing attributes may not be
11528      //  listed in data-sharing attributes clauses, except for the cases
11529      //  listed below. For these exceptions only, listing a predetermined
11530      //  variable in a data-sharing attribute clause is allowed and overrides
11531      //  the variable's predetermined data-sharing attributes.
11532      // OpenMP [2.14.3.6, Restrictions, p.3]
11533      //  Any number of reduction clauses can be specified on the directive,
11534      //  but a list item can appear only once in the reduction clauses for that
11535      //  directive.
11536      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
11537      if (DVar.CKind == OMPC_reduction) {
11538        S.Diag(ELoc, diag::err_omp_once_referenced)
11539            << getOpenMPClauseName(ClauseKind);
11540        if (DVar.RefExpr)
11541          S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
11542        continue;
11543      }
11544      if (DVar.CKind != OMPC_unknown) {
11545        S.Diag(ELoc, diag::err_omp_wrong_dsa)
11546            << getOpenMPClauseName(DVar.CKind)
11547            << getOpenMPClauseName(OMPC_reduction);
11548        reportOriginalDsa(S, Stack, D, DVar);
11549        continue;
11550      }
11551
11552      // OpenMP [2.14.3.6, Restrictions, p.1]
11553      //  A list item that appears in a reduction clause of a worksharing
11554      //  construct must be shared in the parallel regions to which any of the
11555      //  worksharing regions arising from the worksharing construct bind.
11556      if (isOpenMPWorksharingDirective(CurrDir) &&
11557          !isOpenMPParallelDirective(CurrDir) &&
11558          !isOpenMPTeamsDirective(CurrDir)) {
11559        DVar = Stack->getImplicitDSA(D, true);
11560        if (DVar.CKind != OMPC_shared) {
11561          S.Diag(ELoc, diag::err_omp_required_access)
11562              << getOpenMPClauseName(OMPC_reduction)
11563              << getOpenMPClauseName(OMPC_shared);
11564          reportOriginalDsa(S, Stack, D, DVar);
11565          continue;
11566        }
11567      }
11568    }
11569
11570    // Try to find 'declare reduction' corresponding construct before using
11571    // builtin/overloaded operators.
11572    CXXCastPath BasePath;
11573    ExprResult DeclareReductionRef = buildDeclareReductionRef(
11574        S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
11575        ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
11576    if (DeclareReductionRef.isInvalid())
11577      continue;
11578    if (S.CurContext->isDependentContext() &&
11579        (DeclareReductionRef.isUnset() ||
11580         isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
11581      RD.push(RefExpr, DeclareReductionRef.get());
11582      continue;
11583    }
11584    if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
11585      // Not allowed reduction identifier is found.
11586      S.Diag(ReductionId.getBeginLoc(),
11587             diag::err_omp_unknown_reduction_identifier)
11588          << Type << ReductionIdRange;
11589      continue;
11590    }
11591
11592    // OpenMP [2.14.3.6, reduction clause, Restrictions]
11593    // The type of a list item that appears in a reduction clause must be valid
11594    // for the reduction-identifier. For a max or min reduction in C, the type
11595    // of the list item must be an allowed arithmetic data type: char, int,
11596    // float, double, or _Bool, possibly modified with long, short, signed, or
11597    // unsigned. For a max or min reduction in C++, the type of the list item
11598    // must be an allowed arithmetic data type: char, wchar_t, int, float,
11599    // double, or bool, possibly modified with long, short, signed, or unsigned.
11600    if (DeclareReductionRef.isUnset()) {
11601      if ((BOK == BO_GT || BOK == BO_LT) &&
11602          !(Type->isScalarType() ||
11603            (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
11604        S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
11605            << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
11606        if (!ASE && !OASE) {
11607          bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11608                                   VarDecl::DeclarationOnly;
11609          S.Diag(D->getLocation(),
11610                 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11611              << D;
11612        }
11613        continue;
11614      }
11615      if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
11616          !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
11617        S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
11618            << getOpenMPClauseName(ClauseKind);
11619        if (!ASE && !OASE) {
11620          bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11621                                   VarDecl::DeclarationOnly;
11622          S.Diag(D->getLocation(),
11623                 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11624              << D;
11625        }
11626        continue;
11627      }
11628    }
11629
11630    Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
11631    VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
11632                                  D->hasAttrs() ? &D->getAttrs() : nullptr);
11633    VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
11634                                  D->hasAttrs() ? &D->getAttrs() : nullptr);
11635    QualType PrivateTy = Type;
11636
11637    // Try if we can determine constant lengths for all array sections and avoid
11638    // the VLA.
11639    bool ConstantLengthOASE = false;
11640    if (OASE) {
11641      bool SingleElement;
11642      llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
11643      ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
11644          Context, OASE, SingleElement, ArraySizes);
11645
11646      // If we don't have a single element, we must emit a constant array type.
11647      if (ConstantLengthOASE && !SingleElement) {
11648        for (llvm::APSInt &Size : ArraySizes)
11649          PrivateTy = Context.getConstantArrayType(
11650              PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
11651      }
11652    }
11653
11654    if ((OASE && !ConstantLengthOASE) ||
11655        (!OASE && !ASE &&
11656         D->getType().getNonReferenceType()->isVariablyModifiedType())) {
11657      if (!Context.getTargetInfo().isVLASupported() &&
11658          S.shouldDiagnoseTargetSupportFromOpenMP()) {
11659        S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
11660        S.Diag(ELoc, diag::note_vla_unsupported);
11661        continue;
11662      }
11663      // For arrays/array sections only:
11664      // Create pseudo array type for private copy. The size for this array will
11665      // be generated during codegen.
11666      // For array subscripts or single variables Private Ty is the same as Type
11667      // (type of the variable or single array element).
11668      PrivateTy = Context.getVariableArrayType(
11669          Type,
11670          new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
11671          ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
11672    } else if (!ASE && !OASE &&
11673               Context.getAsArrayType(D->getType().getNonReferenceType())) {
11674      PrivateTy = D->getType().getNonReferenceType();
11675    }
11676    // Private copy.
11677    VarDecl *PrivateVD =
11678        buildVarDecl(S, ELoc, PrivateTy, D->getName(),
11679                     D->hasAttrs() ? &D->getAttrs() : nullptr,
11680                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
11681    // Add initializer for private variable.
11682    Expr *Init = nullptr;
11683    DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
11684    DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
11685    if (DeclareReductionRef.isUsable()) {
11686      auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
11687      auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
11688      if (DRD->getInitializer()) {
11689        Init = DRDRef;
11690        RHSVD->setInit(DRDRef);
11691        RHSVD->setInitStyle(VarDecl::CallInit);
11692      }
11693    } else {
11694      switch (BOK) {
11695      case BO_Add:
11696      case BO_Xor:
11697      case BO_Or:
11698      case BO_LOr:
11699        // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
11700        if (Type->isScalarType() || Type->isAnyComplexType())
11701          Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
11702        break;
11703      case BO_Mul:
11704      case BO_LAnd:
11705        if (Type->isScalarType() || Type->isAnyComplexType()) {
11706          // '*' and '&&' reduction ops - initializer is '1'.
11707          Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
11708        }
11709        break;
11710      case BO_And: {
11711        // '&' reduction op - initializer is '~0'.
11712        QualType OrigType = Type;
11713        if (auto *ComplexTy = OrigType->getAs<ComplexType>())
11714          Type = ComplexTy->getElementType();
11715        if (Type->isRealFloatingType()) {
11716          llvm::APFloat InitValue =
11717              llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
11718                                             /*isIEEE=*/true);
11719          Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
11720                                         Type, ELoc);
11721        } else if (Type->isScalarType()) {
11722          uint64_t Size = Context.getTypeSize(Type);
11723          QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
11724          llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
11725          Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
11726        }
11727        if (Init && OrigType->isAnyComplexType()) {
11728          // Init = 0xFFFF + 0xFFFFi;
11729          auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
11730          Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
11731        }
11732        Type = OrigType;
11733        break;
11734      }
11735      case BO_LT:
11736      case BO_GT: {
11737        // 'min' reduction op - initializer is 'Largest representable number in
11738        // the reduction list item type'.
11739        // 'max' reduction op - initializer is 'Least representable number in
11740        // the reduction list item type'.
11741        if (Type->isIntegerType() || Type->isPointerType()) {
11742          bool IsSigned = Type->hasSignedIntegerRepresentation();
11743          uint64_t Size = Context.getTypeSize(Type);
11744          QualType IntTy =
11745              Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
11746          llvm::APInt InitValue =
11747              (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
11748                                        : llvm::APInt::getMinValue(Size)
11749                             : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
11750                                        : llvm::APInt::getMaxValue(Size);
11751          Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
11752          if (Type->isPointerType()) {
11753            // Cast to pointer type.
11754            ExprResult CastExpr = S.BuildCStyleCastExpr(
11755                ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
11756            if (CastExpr.isInvalid())
11757              continue;
11758            Init = CastExpr.get();
11759          }
11760        } else if (Type->isRealFloatingType()) {
11761          llvm::APFloat InitValue = llvm::APFloat::getLargest(
11762              Context.getFloatTypeSemantics(Type), BOK != BO_LT);
11763          Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
11764                                         Type, ELoc);
11765        }
11766        break;
11767      }
11768      case BO_PtrMemD:
11769      case BO_PtrMemI:
11770      case BO_MulAssign:
11771      case BO_Div:
11772      case BO_Rem:
11773      case BO_Sub:
11774      case BO_Shl:
11775      case BO_Shr:
11776      case BO_LE:
11777      case BO_GE:
11778      case BO_EQ:
11779      case BO_NE:
11780      case BO_Cmp:
11781      case BO_AndAssign:
11782      case BO_XorAssign:
11783      case BO_OrAssign:
11784      case BO_Assign:
11785      case BO_AddAssign:
11786      case BO_SubAssign:
11787      case BO_DivAssign:
11788      case BO_RemAssign:
11789      case BO_ShlAssign:
11790      case BO_ShrAssign:
11791      case BO_Comma:
11792        llvm_unreachable("Unexpected reduction operation");
11793      }
11794    }
11795    if (Init && DeclareReductionRef.isUnset())
11796      S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
11797    else if (!Init)
11798      S.ActOnUninitializedDecl(RHSVD);
11799    if (RHSVD->isInvalidDecl())
11800      continue;
11801    if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
11802      S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
11803          << Type << ReductionIdRange;
11804      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11805                               VarDecl::DeclarationOnly;
11806      S.Diag(D->getLocation(),
11807             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11808          << D;
11809      continue;
11810    }
11811    // Store initializer for single element in private copy. Will be used during
11812    // codegen.
11813    PrivateVD->setInit(RHSVD->getInit());
11814    PrivateVD->setInitStyle(RHSVD->getInitStyle());
11815    DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
11816    ExprResult ReductionOp;
11817    if (DeclareReductionRef.isUsable()) {
11818      QualType RedTy = DeclareReductionRef.get()->getType();
11819      QualType PtrRedTy = Context.getPointerType(RedTy);
11820      ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
11821      ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
11822      if (!BasePath.empty()) {
11823        LHS = S.DefaultLvalueConversion(LHS.get());
11824        RHS = S.DefaultLvalueConversion(RHS.get());
11825        LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
11826                                       CK_UncheckedDerivedToBase, LHS.get(),
11827                                       &BasePath, LHS.get()->getValueKind());
11828        RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
11829                                       CK_UncheckedDerivedToBase, RHS.get(),
11830                                       &BasePath, RHS.get()->getValueKind());
11831      }
11832      FunctionProtoType::ExtProtoInfo EPI;
11833      QualType Params[] = {PtrRedTy, PtrRedTy};
11834      QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
11835      auto *OVE = new (Context) OpaqueValueExpr(
11836          ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
11837          S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
11838      Expr *Args[] = {LHS.get(), RHS.get()};
11839      ReductionOp =
11840          CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
11841    } else {
11842      ReductionOp = S.BuildBinOp(
11843          Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
11844      if (ReductionOp.isUsable()) {
11845        if (BOK != BO_LT && BOK != BO_GT) {
11846          ReductionOp =
11847              S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11848                           BO_Assign, LHSDRE, ReductionOp.get());
11849        } else {
11850          auto *ConditionalOp = new (Context)
11851              ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
11852                                  Type, VK_LValue, OK_Ordinary);
11853          ReductionOp =
11854              S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11855                           BO_Assign, LHSDRE, ConditionalOp);
11856        }
11857        if (ReductionOp.isUsable())
11858          ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
11859                                              /*DiscardedValue*/ false);
11860      }
11861      if (!ReductionOp.isUsable())
11862        continue;
11863    }
11864
11865    // OpenMP [2.15.4.6, Restrictions, p.2]
11866    // A list item that appears in an in_reduction clause of a task construct
11867    // must appear in a task_reduction clause of a construct associated with a
11868    // taskgroup region that includes the participating task in its taskgroup
11869    // set. The construct associated with the innermost region that meets this
11870    // condition must specify the same reduction-identifier as the in_reduction
11871    // clause.
11872    if (ClauseKind == OMPC_in_reduction) {
11873      SourceRange ParentSR;
11874      BinaryOperatorKind ParentBOK;
11875      const Expr *ParentReductionOp;
11876      Expr *ParentBOKTD, *ParentReductionOpTD;
11877      DSAStackTy::DSAVarData ParentBOKDSA =
11878          Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
11879                                                  ParentBOKTD);
11880      DSAStackTy::DSAVarData ParentReductionOpDSA =
11881          Stack->getTopMostTaskgroupReductionData(
11882              D, ParentSR, ParentReductionOp, ParentReductionOpTD);
11883      bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
11884      bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
11885      if (!IsParentBOK && !IsParentReductionOp) {
11886        S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
11887        continue;
11888      }
11889      if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
11890          (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
11891          IsParentReductionOp) {
11892        bool EmitError = true;
11893        if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
11894          llvm::FoldingSetNodeID RedId, ParentRedId;
11895          ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
11896          DeclareReductionRef.get()->Profile(RedId, Context,
11897                                             /*Canonical=*/true);
11898          EmitError = RedId != ParentRedId;
11899        }
11900        if (EmitError) {
11901          S.Diag(ReductionId.getBeginLoc(),
11902                 diag::err_omp_reduction_identifier_mismatch)
11903              << ReductionIdRange << RefExpr->getSourceRange();
11904          S.Diag(ParentSR.getBegin(),
11905                 diag::note_omp_previous_reduction_identifier)
11906              << ParentSR
11907              << (IsParentBOK ? ParentBOKDSA.RefExpr
11908                              : ParentReductionOpDSA.RefExpr)
11909                     ->getSourceRange();
11910          continue;
11911        }
11912      }
11913      TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
11914       (0) . __assert_fail ("TaskgroupDescriptor && \"Taskgroup descriptor must be defined.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 11914, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
11915    }
11916
11917    DeclRefExpr *Ref = nullptr;
11918    Expr *VarsExpr = RefExpr->IgnoreParens();
11919    if (!VD && !S.CurContext->isDependentContext()) {
11920      if (ASE || OASE) {
11921        TransformExprToCaptures RebuildToCapture(S, D);
11922        VarsExpr =
11923            RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
11924        Ref = RebuildToCapture.getCapturedExpr();
11925      } else {
11926        VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
11927      }
11928      if (!S.isOpenMPCapturedDecl(D)) {
11929        RD.ExprCaptures.emplace_back(Ref->getDecl());
11930        if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
11931          ExprResult RefRes = S.DefaultLvalueConversion(Ref);
11932          if (!RefRes.isUsable())
11933            continue;
11934          ExprResult PostUpdateRes =
11935              S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
11936                           RefRes.get());
11937          if (!PostUpdateRes.isUsable())
11938            continue;
11939          if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
11940              Stack->getCurrentDirective() == OMPD_taskgroup) {
11941            S.Diag(RefExpr->getExprLoc(),
11942                   diag::err_omp_reduction_non_addressable_expression)
11943                << RefExpr->getSourceRange();
11944            continue;
11945          }
11946          RD.ExprPostUpdates.emplace_back(
11947              S.IgnoredValueConversions(PostUpdateRes.get()).get());
11948        }
11949      }
11950    }
11951    // All reduction items are still marked as reduction (to do not increase
11952    // code base size).
11953    Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
11954    if (CurrDir == OMPD_taskgroup) {
11955      if (DeclareReductionRef.isUsable())
11956        Stack->addTaskgroupReductionData(D, ReductionIdRange,
11957                                         DeclareReductionRef.get());
11958      else
11959        Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
11960    }
11961    RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
11962            TaskgroupDescriptor);
11963  }
11964  return RD.Vars.empty();
11965}
11966
11967OMPClause *Sema::ActOnOpenMPReductionClause(
11968    ArrayRef<Expr *> VarListSourceLocation StartLocSourceLocation LParenLoc,
11969    SourceLocation ColonLocSourceLocation EndLoc,
11970    CXXScopeSpec &ReductionIdScopeSpecconst DeclarationNameInfo &ReductionId,
11971    ArrayRef<Expr *> UnresolvedReductions) {
11972  ReductionData RD(VarList.size());
11973  if (actOnOMPReductionKindClause(*thisDSAStack, OMPC_reduction, VarList,
11974                                  StartLoc, LParenLoc, ColonLoc, EndLoc,
11975                                  ReductionIdScopeSpec, ReductionId,
11976                                  UnresolvedReductions, RD))
11977    return nullptr;
11978
11979  return OMPReductionClause::Create(
11980      ContextStartLocLParenLocColonLocEndLocRD.Vars,
11981      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11982      RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11983      buildPreInits(ContextRD.ExprCaptures),
11984      buildPostUpdate(*thisRD.ExprPostUpdates));
11985}
11986
11987OMPClause *Sema::ActOnOpenMPTaskReductionClause(
11988    ArrayRef<Expr *> VarListSourceLocation StartLocSourceLocation LParenLoc,
11989    SourceLocation ColonLocSourceLocation EndLoc,
11990    CXXScopeSpec &ReductionIdScopeSpecconst DeclarationNameInfo &ReductionId,
11991    ArrayRef<Expr *> UnresolvedReductions) {
11992  ReductionData RD(VarList.size());
11993  if (actOnOMPReductionKindClause(*thisDSAStack, OMPC_task_reduction, VarList,
11994                                  StartLoc, LParenLoc, ColonLoc, EndLoc,
11995                                  ReductionIdScopeSpec, ReductionId,
11996                                  UnresolvedReductions, RD))
11997    return nullptr;
11998
11999  return OMPTaskReductionClause::Create(
12000      ContextStartLocLParenLocColonLocEndLocRD.Vars,
12001      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
12002      RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
12003      buildPreInits(ContextRD.ExprCaptures),
12004      buildPostUpdate(*thisRD.ExprPostUpdates));
12005}
12006
12007OMPClause *Sema::ActOnOpenMPInReductionClause(
12008    ArrayRef<Expr *> VarListSourceLocation StartLocSourceLocation LParenLoc,
12009    SourceLocation ColonLocSourceLocation EndLoc,
12010    CXXScopeSpec &ReductionIdScopeSpecconst DeclarationNameInfo &ReductionId,
12011    ArrayRef<Expr *> UnresolvedReductions) {
12012  ReductionData RD(VarList.size());
12013  if (actOnOMPReductionKindClause(*thisDSAStack, OMPC_in_reduction, VarList,
12014                                  StartLoc, LParenLoc, ColonLoc, EndLoc,
12015                                  ReductionIdScopeSpec, ReductionId,
12016                                  UnresolvedReductions, RD))
12017    return nullptr;
12018
12019  return OMPInReductionClause::Create(
12020      ContextStartLocLParenLocColonLocEndLocRD.Vars,
12021      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
12022      RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
12023      buildPreInits(ContextRD.ExprCaptures),
12024      buildPostUpdate(*thisRD.ExprPostUpdates));
12025}
12026
12027bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
12028                                     SourceLocation LinLoc) {
12029  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
12030      LinKind == OMPC_LINEAR_unknown) {
12031    Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
12032    return true;
12033  }
12034  return false;
12035}
12036
12037bool Sema::CheckOpenMPLinearDecl(const ValueDecl *DSourceLocation ELoc,
12038                                 OpenMPLinearClauseKind LinKind,
12039                                 QualType Type) {
12040  const auto *VD = dyn_cast_or_null<VarDecl>(D);
12041  // A variable must not have an incomplete type or a reference type.
12042  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
12043    return true;
12044  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
12045      !Type->isReferenceType()) {
12046    Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
12047        << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
12048    return true;
12049  }
12050  Type = Type.getNonReferenceType();
12051
12052  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
12053  // A variable that is privatized must not have a const-qualified type
12054  // unless it is of class type with a mutable member. This restriction does
12055  // not apply to the firstprivate clause.
12056  if (rejectConstNotMutableType(*thisDTypeOMPC_linearELoc))
12057    return true;
12058
12059  // A list item must be of integral or pointer type.
12060  Type = Type.getUnqualifiedType().getCanonicalType();
12061  const auto *Ty = Type.getTypePtrOrNull();
12062  if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
12063              !Ty->isPointerType())) {
12064    Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
12065    if (D) {
12066      bool IsDecl =
12067          !VD ||
12068          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12069      Diag(D->getLocation(),
12070           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12071          << D;
12072    }
12073    return true;
12074  }
12075  return false;
12076}
12077
12078OMPClause *Sema::ActOnOpenMPLinearClause(
12079    ArrayRef<Expr *> VarListExpr *StepSourceLocation StartLoc,
12080    SourceLocation LParenLocOpenMPLinearClauseKind LinKind,
12081    SourceLocation LinLocSourceLocation ColonLocSourceLocation EndLoc) {
12082  SmallVector<Expr *, 8Vars;
12083  SmallVector<Expr *, 8Privates;
12084  SmallVector<Expr *, 8Inits;
12085  SmallVector<Decl *, 4ExprCaptures;
12086  SmallVector<Expr *, 4ExprPostUpdates;
12087  if (CheckOpenMPLinearModifier(LinKindLinLoc))
12088    LinKind = OMPC_LINEAR_val;
12089  for (Expr *RefExpr : VarList) {
12090     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 12090, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP linear clause.");
12091    SourceLocation ELoc;
12092    SourceRange ERange;
12093    Expr *SimpleRefExpr = RefExpr;
12094    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12095    if (Res.second) {
12096      // It will be analyzed later.
12097      Vars.push_back(RefExpr);
12098      Privates.push_back(nullptr);
12099      Inits.push_back(nullptr);
12100    }
12101    ValueDecl *D = Res.first;
12102    if (!D)
12103      continue;
12104
12105    QualType Type = D->getType();
12106    auto *VD = dyn_cast<VarDecl>(D);
12107
12108    // OpenMP [2.14.3.7, linear clause]
12109    //  A list-item cannot appear in more than one linear clause.
12110    //  A list-item that appears in a linear clause cannot appear in any
12111    //  other data-sharing attribute clause.
12112    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
12113    if (DVar.RefExpr) {
12114      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
12115                                          << getOpenMPClauseName(OMPC_linear);
12116      reportOriginalDsa(*thisDSAStack, D, DVar);
12117      continue;
12118    }
12119
12120    if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
12121      continue;
12122    Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
12123
12124    // Build private copy of original var.
12125    VarDecl *Private =
12126        buildVarDecl(*this, ELoc, Type, D->getName(),
12127                     D->hasAttrs() ? &D->getAttrs() : nullptr,
12128                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
12129    DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
12130    // Build var to save initial value.
12131    VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
12132    Expr *InitExpr;
12133    DeclRefExpr *Ref = nullptr;
12134    if (!VD && !CurContext->isDependentContext()) {
12135      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
12136      if (!isOpenMPCapturedDecl(D)) {
12137        ExprCaptures.push_back(Ref->getDecl());
12138        if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
12139          ExprResult RefRes = DefaultLvalueConversion(Ref);
12140          if (!RefRes.isUsable())
12141            continue;
12142          ExprResult PostUpdateRes =
12143              BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
12144                         SimpleRefExpr, RefRes.get());
12145          if (!PostUpdateRes.isUsable())
12146            continue;
12147          ExprPostUpdates.push_back(
12148              IgnoredValueConversions(PostUpdateRes.get()).get());
12149        }
12150      }
12151    }
12152    if (LinKind == OMPC_LINEAR_uval)
12153      InitExpr = VD ? VD->getInit() : SimpleRefExpr;
12154    else
12155      InitExpr = VD ? SimpleRefExpr : Ref;
12156    AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
12157                         /*DirectInit=*/false);
12158    DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
12159
12160    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
12161    Vars.push_back((VD || CurContext->isDependentContext())
12162                       ? RefExpr->IgnoreParens()
12163                       : Ref);
12164    Privates.push_back(PrivateRef);
12165    Inits.push_back(InitRef);
12166  }
12167
12168  if (Vars.empty())
12169    return nullptr;
12170
12171  Expr *StepExpr = Step;
12172  Expr *CalcStepExpr = nullptr;
12173  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
12174      !Step->isInstantiationDependent() &&
12175      !Step->containsUnexpandedParameterPack()) {
12176    SourceLocation StepLoc = Step->getBeginLoc();
12177    ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLocStep);
12178    if (Val.isInvalid())
12179      return nullptr;
12180    StepExpr = Val.get();
12181
12182    // Build var to save the step value.
12183    VarDecl *SaveVar =
12184        buildVarDecl(*thisStepLocStepExpr->getType(), ".linear.step");
12185    ExprResult SaveRef =
12186        buildDeclRefExpr(*thisSaveVarStepExpr->getType(), StepLoc);
12187    ExprResult CalcStep =
12188        BuildBinOp(CurScopeStepLocBO_AssignSaveRef.get(), StepExpr);
12189    CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
12190
12191    // Warn about zero linear step (it would be probably better specified as
12192    // making corresponding variables 'const').
12193    llvm::APSInt Result;
12194    bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
12195    if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
12196      Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
12197                                                     << (Vars.size() > 1);
12198    if (!IsConstant && CalcStep.isUsable()) {
12199      // Calculate the step beforehand instead of doing this on each iteration.
12200      // (This is not used if the number of iterations may be kfold-ed).
12201      CalcStepExpr = CalcStep.get();
12202    }
12203  }
12204
12205  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
12206                                 ColonLoc, EndLoc, Vars, Privates, Inits,
12207                                 StepExpr, CalcStepExpr,
12208                                 buildPreInits(Context, ExprCaptures),
12209                                 buildPostUpdate(*this, ExprPostUpdates));
12210}
12211
12212static bool FinishOpenMPLinearClause(OMPLinearClause &ClauseDeclRefExpr *IV,
12213                                     Expr *NumIterationsSema &SemaRef,
12214                                     Scope *SDSAStackTy *Stack) {
12215  // Walk the vars and build update/final expressions for the CodeGen.
12216  SmallVector<Expr *, 8Updates;
12217  SmallVector<Expr *, 8Finals;
12218  Expr *Step = Clause.getStep();
12219  Expr *CalcStep = Clause.getCalcStep();
12220  // OpenMP [2.14.3.7, linear clause]
12221  // If linear-step is not specified it is assumed to be 1.
12222  if (!Step)
12223    Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
12224  else if (CalcStep)
12225    Step = cast<BinaryOperator>(CalcStep)->getLHS();
12226  bool HasErrors = false;
12227  auto CurInit = Clause.inits().begin();
12228  auto CurPrivate = Clause.privates().begin();
12229  OpenMPLinearClauseKind LinKind = Clause.getModifier();
12230  for (Expr *RefExpr : Clause.varlists()) {
12231    SourceLocation ELoc;
12232    SourceRange ERange;
12233    Expr *SimpleRefExpr = RefExpr;
12234    auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
12235    ValueDecl *D = Res.first;
12236    if (Res.second || !D) {
12237      Updates.push_back(nullptr);
12238      Finals.push_back(nullptr);
12239      HasErrors = true;
12240      continue;
12241    }
12242    auto &&Info = Stack->isLoopControlVariable(D);
12243    // OpenMP [2.15.11, distribute simd Construct]
12244    // A list item may not appear in a linear clause, unless it is the loop
12245    // iteration variable.
12246    if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
12247        isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
12248      SemaRef.Diag(ELoc,
12249                   diag::err_omp_linear_distribute_var_non_loop_iteration);
12250      Updates.push_back(nullptr);
12251      Finals.push_back(nullptr);
12252      HasErrors = true;
12253      continue;
12254    }
12255    Expr *InitExpr = *CurInit;
12256
12257    // Build privatized reference to the current linear var.
12258    auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
12259    Expr *CapturedRef;
12260    if (LinKind == OMPC_LINEAR_uval)
12261      CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
12262    else
12263      CapturedRef =
12264          buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
12265                           DE->getType().getUnqualifiedType(), DE->getExprLoc(),
12266                           /*RefersToCapture=*/true);
12267
12268    // Build update: Var = InitExpr + IV * Step
12269    ExprResult Update;
12270    if (!Info.first)
12271      Update =
12272          buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
12273                             InitExpr, IV, Step, /* Subtract */ false);
12274    else
12275      Update = *CurPrivate;
12276    Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
12277                                         /*DiscardedValue*/ false);
12278
12279    // Build final: Var = InitExpr + NumIterations * Step
12280    ExprResult Final;
12281    if (!Info.first)
12282      Final =
12283          buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
12284                             InitExpr, NumIterations, Step, /*Subtract=*/false);
12285    else
12286      Final = *CurPrivate;
12287    Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
12288                                        /*DiscardedValue*/ false);
12289
12290    if (!Update.isUsable() || !Final.isUsable()) {
12291      Updates.push_back(nullptr);
12292      Finals.push_back(nullptr);
12293      HasErrors = true;
12294    } else {
12295      Updates.push_back(Update.get());
12296      Finals.push_back(Final.get());
12297    }
12298    ++CurInit;
12299    ++CurPrivate;
12300  }
12301  Clause.setUpdates(Updates);
12302  Clause.setFinals(Finals);
12303  return HasErrors;
12304}
12305
12306OMPClause *Sema::ActOnOpenMPAlignedClause(
12307    ArrayRef<Expr *> VarListExpr *AlignmentSourceLocation StartLoc,
12308    SourceLocation LParenLocSourceLocation ColonLocSourceLocation EndLoc) {
12309  SmallVector<Expr *, 8Vars;
12310  for (Expr *RefExpr : VarList) {
12311     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 12311, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP linear clause.");
12312    SourceLocation ELoc;
12313    SourceRange ERange;
12314    Expr *SimpleRefExpr = RefExpr;
12315    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12316    if (Res.second) {
12317      // It will be analyzed later.
12318      Vars.push_back(RefExpr);
12319    }
12320    ValueDecl *D = Res.first;
12321    if (!D)
12322      continue;
12323
12324    QualType QType = D->getType();
12325    auto *VD = dyn_cast<VarDecl>(D);
12326
12327    // OpenMP  [2.8.1, simd construct, Restrictions]
12328    // The type of list items appearing in the aligned clause must be
12329    // array, pointer, reference to array, or reference to pointer.
12330    QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
12331    const Type *Ty = QType.getTypePtrOrNull();
12332    if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
12333      Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
12334          << QType << getLangOpts().CPlusPlus << ERange;
12335      bool IsDecl =
12336          !VD ||
12337          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12338      Diag(D->getLocation(),
12339           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12340          << D;
12341      continue;
12342    }
12343
12344    // OpenMP  [2.8.1, simd construct, Restrictions]
12345    // A list-item cannot appear in more than one aligned clause.
12346    if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
12347      Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
12348      Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
12349          << getOpenMPClauseName(OMPC_aligned);
12350      continue;
12351    }
12352
12353    DeclRefExpr *Ref = nullptr;
12354    if (!VD && isOpenMPCapturedDecl(D))
12355      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
12356    Vars.push_back(DefaultFunctionArrayConversion(
12357                       (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
12358                       .get());
12359  }
12360
12361  // OpenMP [2.8.1, simd construct, Description]
12362  // The parameter of the aligned clause, alignment, must be a constant
12363  // positive integer expression.
12364  // If no optional parameter is specified, implementation-defined default
12365  // alignments for SIMD instructions on the target platforms are assumed.
12366  if (Alignment != nullptr) {
12367    ExprResult AlignResult =
12368        VerifyPositiveIntegerConstantInClause(AlignmentOMPC_aligned);
12369    if (AlignResult.isInvalid())
12370      return nullptr;
12371    Alignment = AlignResult.get();
12372  }
12373  if (Vars.empty())
12374    return nullptr;
12375
12376  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
12377                                  EndLoc, Vars, Alignment);
12378}
12379
12380OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
12381                                         SourceLocation StartLoc,
12382                                         SourceLocation LParenLoc,
12383                                         SourceLocation EndLoc) {
12384  SmallVector<Expr *, 8Vars;
12385  SmallVector<Expr *, 8SrcExprs;
12386  SmallVector<Expr *, 8DstExprs;
12387  SmallVector<Expr *, 8AssignmentOps;
12388  for (Expr *RefExpr : VarList) {
12389     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP copyin clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 12389, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP copyin clause.");
12390    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
12391      // It will be analyzed later.
12392      Vars.push_back(RefExpr);
12393      SrcExprs.push_back(nullptr);
12394      DstExprs.push_back(nullptr);
12395      AssignmentOps.push_back(nullptr);
12396      continue;
12397    }
12398
12399    SourceLocation ELoc = RefExpr->getExprLoc();
12400    // OpenMP [2.1, C/C++]
12401    //  A list item is a variable name.
12402    // OpenMP  [2.14.4.1, Restrictions, p.1]
12403    //  A list item that appears in a copyin clause must be threadprivate.
12404    auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
12405    if (!DE || !isa<VarDecl>(DE->getDecl())) {
12406      Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
12407          << 0 << RefExpr->getSourceRange();
12408      continue;
12409    }
12410
12411    Decl *D = DE->getDecl();
12412    auto *VD = cast<VarDecl>(D);
12413
12414    QualType Type = VD->getType();
12415    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
12416      // It will be analyzed later.
12417      Vars.push_back(DE);
12418      SrcExprs.push_back(nullptr);
12419      DstExprs.push_back(nullptr);
12420      AssignmentOps.push_back(nullptr);
12421      continue;
12422    }
12423
12424    // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
12425    //  A list item that appears in a copyin clause must be threadprivate.
12426    if (!DSAStack->isThreadPrivate(VD)) {
12427      Diag(ELoc, diag::err_omp_required_access)
12428          << getOpenMPClauseName(OMPC_copyin)
12429          << getOpenMPDirectiveName(OMPD_threadprivate);
12430      continue;
12431    }
12432
12433    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
12434    //  A variable of class type (or array thereof) that appears in a
12435    //  copyin clause requires an accessible, unambiguous copy assignment
12436    //  operator for the class type.
12437    QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
12438    VarDecl *SrcVD =
12439        buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
12440                     ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
12441    DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
12442        *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
12443    VarDecl *DstVD =
12444        buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
12445                     VD->hasAttrs() ? &VD->getAttrs() : nullptr);
12446    DeclRefExpr *PseudoDstExpr =
12447        buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
12448    // For arrays generate assignment operation for single element and replace
12449    // it by the original array element in CodeGen.
12450    ExprResult AssignmentOp =
12451        BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
12452                   PseudoSrcExpr);
12453    if (AssignmentOp.isInvalid())
12454      continue;
12455    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
12456                                       /*DiscardedValue*/ false);
12457    if (AssignmentOp.isInvalid())
12458      continue;
12459
12460    DSAStack->addDSA(VD, DE, OMPC_copyin);
12461    Vars.push_back(DE);
12462    SrcExprs.push_back(PseudoSrcExpr);
12463    DstExprs.push_back(PseudoDstExpr);
12464    AssignmentOps.push_back(AssignmentOp.get());
12465  }
12466
12467  if (Vars.empty())
12468    return nullptr;
12469
12470  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
12471                                 SrcExprs, DstExprs, AssignmentOps);
12472}
12473
12474OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
12475                                              SourceLocation StartLoc,
12476                                              SourceLocation LParenLoc,
12477                                              SourceLocation EndLoc) {
12478  SmallVector<Expr *, 8Vars;
12479  SmallVector<Expr *, 8SrcExprs;
12480  SmallVector<Expr *, 8DstExprs;
12481  SmallVector<Expr *, 8AssignmentOps;
12482  for (Expr *RefExpr : VarList) {
12483     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 12483, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP linear clause.");
12484    SourceLocation ELoc;
12485    SourceRange ERange;
12486    Expr *SimpleRefExpr = RefExpr;
12487    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12488    if (Res.second) {
12489      // It will be analyzed later.
12490      Vars.push_back(RefExpr);
12491      SrcExprs.push_back(nullptr);
12492      DstExprs.push_back(nullptr);
12493      AssignmentOps.push_back(nullptr);
12494    }
12495    ValueDecl *D = Res.first;
12496    if (!D)
12497      continue;
12498
12499    QualType Type = D->getType();
12500    auto *VD = dyn_cast<VarDecl>(D);
12501
12502    // OpenMP [2.14.4.2, Restrictions, p.2]
12503    //  A list item that appears in a copyprivate clause may not appear in a
12504    //  private or firstprivate clause on the single construct.
12505    if (!VD || !DSAStack->isThreadPrivate(VD)) {
12506      DSAStackTy::DSAVarData DVar =
12507          DSAStack->getTopDSA(D, /*FromParent=*/false);
12508      if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
12509          DVar.RefExpr) {
12510        Diag(ELoc, diag::err_omp_wrong_dsa)
12511            << getOpenMPClauseName(DVar.CKind)
12512            << getOpenMPClauseName(OMPC_copyprivate);
12513        reportOriginalDsa(*thisDSAStack, D, DVar);
12514        continue;
12515      }
12516
12517      // OpenMP [2.11.4.2, Restrictions, p.1]
12518      //  All list items that appear in a copyprivate clause must be either
12519      //  threadprivate or private in the enclosing context.
12520      if (DVar.CKind == OMPC_unknown) {
12521        DVar = DSAStack->getImplicitDSA(D, false);
12522        if (DVar.CKind == OMPC_shared) {
12523          Diag(ELoc, diag::err_omp_required_access)
12524              << getOpenMPClauseName(OMPC_copyprivate)
12525              << "threadprivate or private in the enclosing context";
12526          reportOriginalDsa(*thisDSAStack, D, DVar);
12527          continue;
12528        }
12529      }
12530    }
12531
12532    // Variably modified types are not supported.
12533    if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
12534      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12535          << getOpenMPClauseName(OMPC_copyprivate) << Type
12536          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12537      bool IsDecl =
12538          !VD ||
12539          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12540      Diag(D->getLocation(),
12541           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12542          << D;
12543      continue;
12544    }
12545
12546    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
12547    //  A variable of class type (or array thereof) that appears in a
12548    //  copyin clause requires an accessible, unambiguous copy assignment
12549    //  operator for the class type.
12550    Type = Context.getBaseElementType(Type.getNonReferenceType())
12551               .getUnqualifiedType();
12552    VarDecl *SrcVD =
12553        buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
12554                     D->hasAttrs() ? &D->getAttrs() : nullptr);
12555    DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
12556    VarDecl *DstVD =
12557        buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
12558                     D->hasAttrs() ? &D->getAttrs() : nullptr);
12559    DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
12560    ExprResult AssignmentOp = BuildBinOp(
12561        DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
12562    if (AssignmentOp.isInvalid())
12563      continue;
12564    AssignmentOp =
12565        ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
12566    if (AssignmentOp.isInvalid())
12567      continue;
12568
12569    // No need to mark vars as copyprivate, they are already threadprivate or
12570    // implicitly private.
12571    assert(VD || isOpenMPCapturedDecl(D));
12572    Vars.push_back(
12573        VD ? RefExpr->IgnoreParens()
12574           : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
12575    SrcExprs.push_back(PseudoSrcExpr);
12576    DstExprs.push_back(PseudoDstExpr);
12577    AssignmentOps.push_back(AssignmentOp.get());
12578  }
12579
12580  if (Vars.empty())
12581    return nullptr;
12582
12583  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12584                                      Vars, SrcExprs, DstExprs, AssignmentOps);
12585}
12586
12587OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
12588                                        SourceLocation StartLoc,
12589                                        SourceLocation LParenLoc,
12590                                        SourceLocation EndLoc) {
12591  if (VarList.empty())
12592    return nullptr;
12593
12594  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
12595}
12596
12597OMPClause *
12598Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
12599                              SourceLocation DepLocSourceLocation ColonLoc,
12600                              ArrayRef<Expr *> VarListSourceLocation StartLoc,
12601                              SourceLocation LParenLocSourceLocation EndLoc) {
12602  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
12603      DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
12604    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12605        << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
12606    return nullptr;
12607  }
12608  if (DSAStack->getCurrentDirective() != OMPD_ordered &&
12609      (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
12610       DepKind == OMPC_DEPEND_sink)) {
12611    unsigned Except[] = {OMPC_DEPEND_sourceOMPC_DEPEND_sink};
12612    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12613        << getListOfPossibleValues(OMPC_depend, /*First=*/0,
12614                                   /*Last=*/OMPC_DEPEND_unknown, Except)
12615        << getOpenMPClauseName(OMPC_depend);
12616    return nullptr;
12617  }
12618  SmallVector<Expr *, 8Vars;
12619  DSAStackTy::OperatorOffsetTy OpsOffs;
12620  llvm::APSInt DepCounter(/*BitWidth=*/32);
12621  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
12622  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
12623    if (const Expr *OrderedCountExpr =
12624            DSAStack->getParentOrderedRegionParam().first) {
12625      TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
12626      TotalDepCount.setIsUnsigned(/*Val=*/true);
12627    }
12628  }
12629  for (Expr *RefExpr : VarList) {
12630     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 12630, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP shared clause.");
12631    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
12632      // It will be analyzed later.
12633      Vars.push_back(RefExpr);
12634      continue;
12635    }
12636
12637    SourceLocation ELoc = RefExpr->getExprLoc();
12638    Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
12639    if (DepKind == OMPC_DEPEND_sink) {
12640      if (DSAStack->getParentOrderedRegionParam().first &&
12641          DepCounter >= TotalDepCount) {
12642        Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
12643        continue;
12644      }
12645      ++DepCounter;
12646      // OpenMP  [2.13.9, Summary]
12647      // depend(dependence-type : vec), where dependence-type is:
12648      // 'sink' and where vec is the iteration vector, which has the form:
12649      //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
12650      // where n is the value specified by the ordered clause in the loop
12651      // directive, xi denotes the loop iteration variable of the i-th nested
12652      // loop associated with the loop directive, and di is a constant
12653      // non-negative integer.
12654      if (CurContext->isDependentContext()) {
12655        // It will be analyzed later.
12656        Vars.push_back(RefExpr);
12657        continue;
12658      }
12659      SimpleExpr = SimpleExpr->IgnoreImplicit();
12660      OverloadedOperatorKind OOK = OO_None;
12661      SourceLocation OOLoc;
12662      Expr *LHS = SimpleExpr;
12663      Expr *RHS = nullptr;
12664      if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
12665        OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
12666        OOLoc = BO->getOperatorLoc();
12667        LHS = BO->getLHS()->IgnoreParenImpCasts();
12668        RHS = BO->getRHS()->IgnoreParenImpCasts();
12669      } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
12670        OOK = OCE->getOperator();
12671        OOLoc = OCE->getOperatorLoc();
12672        LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
12673        RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
12674      } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
12675        OOK = MCE->getMethodDecl()
12676                  ->getNameInfo()
12677                  .getName()
12678                  .getCXXOverloadedOperator();
12679        OOLoc = MCE->getCallee()->getExprLoc();
12680        LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
12681        RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
12682      }
12683      SourceLocation ELoc;
12684      SourceRange ERange;
12685      auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
12686      if (Res.second) {
12687        // It will be analyzed later.
12688        Vars.push_back(RefExpr);
12689      }
12690      ValueDecl *D = Res.first;
12691      if (!D)
12692        continue;
12693
12694      if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
12695        Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
12696        continue;
12697      }
12698      if (RHS) {
12699        ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
12700            RHS, OMPC_depend, /*StrictlyPositive=*/false);
12701        if (RHSRes.isInvalid())
12702          continue;
12703      }
12704      if (!CurContext->isDependentContext() &&
12705          DSAStack->getParentOrderedRegionParam().first &&
12706          DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
12707        const ValueDecl *VD =
12708            DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
12709        if (VD)
12710          Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
12711              << 1 << VD;
12712        else
12713          Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
12714        continue;
12715      }
12716      OpsOffs.emplace_back(RHS, OOK);
12717    } else {
12718      auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
12719      if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
12720          (ASE &&
12721           !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
12722           !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
12723        Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12724            << RefExpr->getSourceRange();
12725        continue;
12726      }
12727      bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
12728      getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
12729      ExprResult Res =
12730          CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
12731      getDiagnostics().setSuppressAllDiagnostics(Suppress);
12732      if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
12733        Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12734            << RefExpr->getSourceRange();
12735        continue;
12736      }
12737    }
12738    Vars.push_back(RefExpr->IgnoreParenImpCasts());
12739  }
12740
12741  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
12742      TotalDepCount > VarList.size() &&
12743      DSAStack->getParentOrderedRegionParam().first &&
12744      DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
12745    Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
12746        << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
12747  }
12748  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
12749      Vars.empty())
12750    return nullptr;
12751
12752  auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12753                                    DepKind, DepLoc, ColonLoc, Vars,
12754                                    TotalDepCount.getZExtValue());
12755  if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
12756      DSAStack->isParentOrderedRegion())
12757    DSAStack->addDoacrossDependClause(C, OpsOffs);
12758  return C;
12759}
12760
12761OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *DeviceSourceLocation StartLoc,
12762                                         SourceLocation LParenLoc,
12763                                         SourceLocation EndLoc) {
12764  Expr *ValExpr = Device;
12765  Stmt *HelperValStmt = nullptr;
12766
12767  // OpenMP [2.9.1, Restrictions]
12768  // The device expression must evaluate to a non-negative integer value.
12769  if (!isNonNegativeIntegerValue(ValExpr*thisOMPC_device,
12770                                 /*StrictlyPositive=*/false))
12771    return nullptr;
12772
12773  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12774  OpenMPDirectiveKind CaptureRegion =
12775      getOpenMPCaptureRegionForClause(DKindOMPC_device);
12776  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12777    ValExpr = MakeFullExpr(ValExpr).get();
12778    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12779    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12780    HelperValStmt = buildPreInits(Context, Captures);
12781  }
12782
12783  return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
12784                                       StartLoc, LParenLoc, EndLoc);
12785}
12786
12787static bool checkTypeMappable(SourceLocation SLSourceRange SRSema &SemaRef,
12788                              DSAStackTy *StackQualType QTy,
12789                              bool FullCheck = true) {
12790  NamedDecl *ND;
12791  if (QTy->isIncompleteType(&ND)) {
12792    SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
12793    return false;
12794  }
12795  if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
12796      !QTy.isTrivialType(SemaRef.Context))
12797    SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
12798  return true;
12799}
12800
12801/// Return true if it can be proven that the provided array expression
12802/// (array section or array subscript) does NOT specify the whole size of the
12803/// array whose base type is \a BaseQTy.
12804static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
12805                                                        const Expr *E,
12806                                                        QualType BaseQTy) {
12807  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
12808
12809  // If this is an array subscript, it refers to the whole size if the size of
12810  // the dimension is constant and equals 1. Also, an array section assumes the
12811  // format of an array subscript if no colon is used.
12812  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
12813    if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
12814      return ATy->getSize().getSExtValue() != 1;
12815    // Size can't be evaluated statically.
12816    return false;
12817  }
12818
12819   (0) . __assert_fail ("OASE && \"Expecting array section if not an array subscript.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 12819, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(OASE && "Expecting array section if not an array subscript.");
12820  const Expr *LowerBound = OASE->getLowerBound();
12821  const Expr *Length = OASE->getLength();
12822
12823  // If there is a lower bound that does not evaluates to zero, we are not
12824  // covering the whole dimension.
12825  if (LowerBound) {
12826    Expr::EvalResult Result;
12827    if (!LowerBound->EvaluateAsInt(ResultSemaRef.getASTContext()))
12828      return false// Can't get the integer value as a constant.
12829
12830    llvm::APSInt ConstLowerBound = Result.Val.getInt();
12831    if (ConstLowerBound.getSExtValue())
12832      return true;
12833  }
12834
12835  // If we don't have a length we covering the whole dimension.
12836  if (!Length)
12837    return false;
12838
12839  // If the base is a pointer, we don't have a way to get the size of the
12840  // pointee.
12841  if (BaseQTy->isPointerType())
12842    return false;
12843
12844  // We can only check if the length is the same as the size of the dimension
12845  // if we have a constant array.
12846  const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
12847  if (!CATy)
12848    return false;
12849
12850  Expr::EvalResult Result;
12851  if (!Length->EvaluateAsInt(ResultSemaRef.getASTContext()))
12852    return false// Can't get the integer value as a constant.
12853
12854  llvm::APSInt ConstLength = Result.Val.getInt();
12855  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
12856}
12857
12858// Return true if it can be proven that the provided array expression (array
12859// section or array subscript) does NOT specify a single element of the array
12860// whose base type is \a BaseQTy.
12861static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
12862                                                        const Expr *E,
12863                                                        QualType BaseQTy) {
12864  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
12865
12866  // An array subscript always refer to a single element. Also, an array section
12867  // assumes the format of an array subscript if no colon is used.
12868  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
12869    return false;
12870
12871   (0) . __assert_fail ("OASE && \"Expecting array section if not an array subscript.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 12871, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(OASE && "Expecting array section if not an array subscript.");
12872  const Expr *Length = OASE->getLength();
12873
12874  // If we don't have a length we have to check if the array has unitary size
12875  // for this dimension. Also, we should always expect a length if the base type
12876  // is pointer.
12877  if (!Length) {
12878    if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
12879      return ATy->getSize().getSExtValue() != 1;
12880    // We cannot assume anything.
12881    return false;
12882  }
12883
12884  // Check if the length evaluates to 1.
12885  Expr::EvalResult Result;
12886  if (!Length->EvaluateAsInt(ResultSemaRef.getASTContext()))
12887    return false// Can't get the integer value as a constant.
12888
12889  llvm::APSInt ConstLength = Result.Val.getInt();
12890  return ConstLength.getSExtValue() != 1;
12891}
12892
12893// Return the expression of the base of the mappable expression or null if it
12894// cannot be determined and do all the necessary checks to see if the expression
12895// is valid as a standalone mappable expression. In the process, record all the
12896// components of the expression.
12897static const Expr *checkMapClauseExpressionBase(
12898    Sema &SemaRefExpr *E,
12899    OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
12900    OpenMPClauseKind CKindbool NoDiagnose) {
12901  SourceLocation ELoc = E->getExprLoc();
12902  SourceRange ERange = E->getSourceRange();
12903
12904  // The base of elements of list in a map clause have to be either:
12905  //  - a reference to variable or field.
12906  //  - a member expression.
12907  //  - an array expression.
12908  //
12909  // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
12910  // reference to 'r'.
12911  //
12912  // If we have:
12913  //
12914  // struct SS {
12915  //   Bla S;
12916  //   foo() {
12917  //     #pragma omp target map (S.Arr[:12]);
12918  //   }
12919  // }
12920  //
12921  // We want to retrieve the member expression 'this->S';
12922
12923  const Expr *RelevantExpr = nullptr;
12924
12925  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
12926  //  If a list item is an array section, it must specify contiguous storage.
12927  //
12928  // For this restriction it is sufficient that we make sure only references
12929  // to variables or fields and array expressions, and that no array sections
12930  // exist except in the rightmost expression (unless they cover the whole
12931  // dimension of the array). E.g. these would be invalid:
12932  //
12933  //   r.ArrS[3:5].Arr[6:7]
12934  //
12935  //   r.ArrS[3:5].x
12936  //
12937  // but these would be valid:
12938  //   r.ArrS[3].Arr[6:7]
12939  //
12940  //   r.ArrS[3].x
12941
12942  bool AllowUnitySizeArraySection = true;
12943  bool AllowWholeSizeArraySection = true;
12944
12945  while (!RelevantExpr) {
12946    E = E->IgnoreParenImpCasts();
12947
12948    if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
12949      if (!isa<VarDecl>(CurE->getDecl()))
12950        return nullptr;
12951
12952      RelevantExpr = CurE;
12953
12954      // If we got a reference to a declaration, we should not expect any array
12955      // section before that.
12956      AllowUnitySizeArraySection = false;
12957      AllowWholeSizeArraySection = false;
12958
12959      // Record the component.
12960      CurComponents.emplace_back(CurE, CurE->getDecl());
12961    } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
12962      Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
12963
12964      if (isa<CXXThisExpr>(BaseE))
12965        // We found a base expression: this->Val.
12966        RelevantExpr = CurE;
12967      else
12968        E = BaseE;
12969
12970      if (!isa<FieldDecl>(CurE->getMemberDecl())) {
12971        if (!NoDiagnose) {
12972          SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
12973              << CurE->getSourceRange();
12974          return nullptr;
12975        }
12976        if (RelevantExpr)
12977          return nullptr;
12978        continue;
12979      }
12980
12981      auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
12982
12983      // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
12984      //  A bit-field cannot appear in a map clause.
12985      //
12986      if (FD->isBitField()) {
12987        if (!NoDiagnose) {
12988          SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
12989              << CurE->getSourceRange() << getOpenMPClauseName(CKind);
12990          return nullptr;
12991        }
12992        if (RelevantExpr)
12993          return nullptr;
12994        continue;
12995      }
12996
12997      // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12998      //  If the type of a list item is a reference to a type T then the type
12999      //  will be considered to be T for all purposes of this clause.
13000      QualType CurType = BaseE->getType().getNonReferenceType();
13001
13002      // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
13003      //  A list item cannot be a variable that is a member of a structure with
13004      //  a union type.
13005      //
13006      if (CurType->isUnionType()) {
13007        if (!NoDiagnose) {
13008          SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
13009              << CurE->getSourceRange();
13010          return nullptr;
13011        }
13012        continue;
13013      }
13014
13015      // If we got a member expression, we should not expect any array section
13016      // before that:
13017      //
13018      // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
13019      //  If a list item is an element of a structure, only the rightmost symbol
13020      //  of the variable reference can be an array section.
13021      //
13022      AllowUnitySizeArraySection = false;
13023      AllowWholeSizeArraySection = false;
13024
13025      // Record the component.
13026      CurComponents.emplace_back(CurE, FD);
13027    } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
13028      E = CurE->getBase()->IgnoreParenImpCasts();
13029
13030      if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
13031        if (!NoDiagnose) {
13032          SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
13033              << 0 << CurE->getSourceRange();
13034          return nullptr;
13035        }
13036        continue;
13037      }
13038
13039      // If we got an array subscript that express the whole dimension we
13040      // can have any array expressions before. If it only expressing part of
13041      // the dimension, we can only have unitary-size array expressions.
13042      if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
13043                                                      E->getType()))
13044        AllowWholeSizeArraySection = false;
13045
13046      if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
13047        Expr::EvalResult Result;
13048        if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) {
13049          if (!Result.Val.getInt().isNullValue()) {
13050            SemaRef.Diag(CurE->getIdx()->getExprLoc(),
13051                         diag::err_omp_invalid_map_this_expr);
13052            SemaRef.Diag(CurE->getIdx()->getExprLoc(),
13053                         diag::note_omp_invalid_subscript_on_this_ptr_map);
13054          }
13055        }
13056        RelevantExpr = TE;
13057      }
13058
13059      // Record the component - we don't have any declaration associated.
13060      CurComponents.emplace_back(CurE, nullptr);
13061    } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
13062       (0) . __assert_fail ("!NoDiagnose && \"Array sections cannot be implicitly mapped.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13062, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
13063      E = CurE->getBase()->IgnoreParenImpCasts();
13064
13065      QualType CurType =
13066          OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
13067
13068      // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
13069      //  If the type of a list item is a reference to a type T then the type
13070      //  will be considered to be T for all purposes of this clause.
13071      if (CurType->isReferenceType())
13072        CurType = CurType->getPointeeType();
13073
13074      bool IsPointer = CurType->isAnyPointerType();
13075
13076      if (!IsPointer && !CurType->isArrayType()) {
13077        SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
13078            << 0 << CurE->getSourceRange();
13079        return nullptr;
13080      }
13081
13082      bool NotWhole =
13083          checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
13084      bool NotUnity =
13085          checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
13086
13087      if (AllowWholeSizeArraySection) {
13088        // Any array section is currently allowed. Allowing a whole size array
13089        // section implies allowing a unity array section as well.
13090        //
13091        // If this array section refers to the whole dimension we can still
13092        // accept other array sections before this one, except if the base is a
13093        // pointer. Otherwise, only unitary sections are accepted.
13094        if (NotWhole || IsPointer)
13095          AllowWholeSizeArraySection = false;
13096      } else if (AllowUnitySizeArraySection && NotUnity) {
13097        // A unity or whole array section is not allowed and that is not
13098        // compatible with the properties of the current array section.
13099        SemaRef.Diag(
13100            ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
13101            << CurE->getSourceRange();
13102        return nullptr;
13103      }
13104
13105      if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
13106        Expr::EvalResult ResultR;
13107        Expr::EvalResult ResultL;
13108        if (CurE->getLength()->EvaluateAsInt(ResultR,
13109                                             SemaRef.getASTContext())) {
13110          if (!ResultR.Val.getInt().isOneValue()) {
13111            SemaRef.Diag(CurE->getLength()->getExprLoc(),
13112                         diag::err_omp_invalid_map_this_expr);
13113            SemaRef.Diag(CurE->getLength()->getExprLoc(),
13114                         diag::note_omp_invalid_length_on_this_ptr_mapping);
13115          }
13116        }
13117        if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
13118                                        ResultL, SemaRef.getASTContext())) {
13119          if (!ResultL.Val.getInt().isNullValue()) {
13120            SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
13121                         diag::err_omp_invalid_map_this_expr);
13122            SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
13123                         diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
13124          }
13125        }
13126        RelevantExpr = TE;
13127      }
13128
13129      // Record the component - we don't have any declaration associated.
13130      CurComponents.emplace_back(CurE, nullptr);
13131    } else {
13132      if (!NoDiagnose) {
13133        // If nothing else worked, this is not a valid map clause expression.
13134        SemaRef.Diag(
13135            ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
13136            << ERange;
13137      }
13138      return nullptr;
13139    }
13140  }
13141
13142  return RelevantExpr;
13143}
13144
13145// Return true if expression E associated with value VD has conflicts with other
13146// map information.
13147static bool checkMapConflicts(
13148    Sema &SemaRefDSAStackTy *DSASconst ValueDecl *VDconst Expr *E,
13149    bool CurrentRegionOnly,
13150    OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
13151    OpenMPClauseKind CKind) {
13152  assert(VD && E);
13153  SourceLocation ELoc = E->getExprLoc();
13154  SourceRange ERange = E->getSourceRange();
13155
13156  // In order to easily check the conflicts we need to match each component of
13157  // the expression under test with the components of the expressions that are
13158  // already in the stack.
13159
13160   (0) . __assert_fail ("!CurComponents.empty() && \"Map clause expression with no components!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13160, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!CurComponents.empty() && "Map clause expression with no components!");
13161   (0) . __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13162, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CurComponents.back().getAssociatedDeclaration() == VD &&
13162 (0) . __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13162, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Map clause expression with unexpected base!");
13163
13164  // Variables to help detecting enclosing problems in data environment nests.
13165  bool IsEnclosedByDataEnvironmentExpr = false;
13166  const Expr *EnclosingExpr = nullptr;
13167
13168  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
13169      VDCurrentRegionOnly,
13170      [&IsEnclosedByDataEnvironmentExpr, &SemaRefVDCurrentRegionOnlyELoc,
13171       ERangeCKind, &EnclosingExpr,
13172       CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
13173                          StackComponents,
13174                      OpenMPClauseKind) {
13175         (0) . __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13176, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!StackComponents.empty() &&
13176 (0) . __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13176, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">               "Map clause expression with no components!");
13177         (0) . __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13178, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(StackComponents.back().getAssociatedDeclaration() == VD &&
13178 (0) . __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13178, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">               "Map clause expression with unexpected base!");
13179        (void)VD;
13180
13181        // The whole expression in the stack.
13182        const Expr *RE = StackComponents.front().getAssociatedExpression();
13183
13184        // Expressions must start from the same base. Here we detect at which
13185        // point both expressions diverge from each other and see if we can
13186        // detect if the memory referred to both expressions is contiguous and
13187        // do not overlap.
13188        auto CI = CurComponents.rbegin();
13189        auto CE = CurComponents.rend();
13190        auto SI = StackComponents.rbegin();
13191        auto SE = StackComponents.rend();
13192        for (; CI != CE && SI != SE; ++CI, ++SI) {
13193
13194          // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
13195          //  At most one list item can be an array item derived from a given
13196          //  variable in map clauses of the same construct.
13197          if (CurrentRegionOnly &&
13198              (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
13199               isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
13200              (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
13201               isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
13202            SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
13203                         diag::err_omp_multiple_array_items_in_map_clause)
13204                << CI->getAssociatedExpression()->getSourceRange();
13205            SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
13206                         diag::note_used_here)
13207                << SI->getAssociatedExpression()->getSourceRange();
13208            return true;
13209          }
13210
13211          // Do both expressions have the same kind?
13212          if (CI->getAssociatedExpression()->getStmtClass() !=
13213              SI->getAssociatedExpression()->getStmtClass())
13214            break;
13215
13216          // Are we dealing with different variables/fields?
13217          if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
13218            break;
13219        }
13220        // Check if the extra components of the expressions in the enclosing
13221        // data environment are redundant for the current base declaration.
13222        // If they are, the maps completely overlap, which is legal.
13223        for (; SI != SE; ++SI) {
13224          QualType Type;
13225          if (const auto *ASE =
13226                  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
13227            Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
13228          } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
13229                         SI->getAssociatedExpression())) {
13230            const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
13231            Type =
13232                OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
13233          }
13234          if (Type.isNull() || Type->isAnyPointerType() ||
13235              checkArrayExpressionDoesNotReferToWholeSize(
13236                  SemaRef, SI->getAssociatedExpression(), Type))
13237            break;
13238        }
13239
13240        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
13241        //  List items of map clauses in the same construct must not share
13242        //  original storage.
13243        //
13244        // If the expressions are exactly the same or one is a subset of the
13245        // other, it means they are sharing storage.
13246        if (CI == CE && SI == SE) {
13247          if (CurrentRegionOnly) {
13248            if (CKind == OMPC_map) {
13249              SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
13250            } else {
13251              assert(CKind == OMPC_to || CKind == OMPC_from);
13252              SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
13253                  << ERange;
13254            }
13255            SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
13256                << RE->getSourceRange();
13257            return true;
13258          }
13259          // If we find the same expression in the enclosing data environment,
13260          // that is legal.
13261          IsEnclosedByDataEnvironmentExpr = true;
13262          return false;
13263        }
13264
13265        QualType DerivedType =
13266            std::prev(CI)->getAssociatedDeclaration()->getType();
13267        SourceLocation DerivedLoc =
13268            std::prev(CI)->getAssociatedExpression()->getExprLoc();
13269
13270        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
13271        //  If the type of a list item is a reference to a type T then the type
13272        //  will be considered to be T for all purposes of this clause.
13273        DerivedType = DerivedType.getNonReferenceType();
13274
13275        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
13276        //  A variable for which the type is pointer and an array section
13277        //  derived from that variable must not appear as list items of map
13278        //  clauses of the same construct.
13279        //
13280        // Also, cover one of the cases in:
13281        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
13282        //  If any part of the original storage of a list item has corresponding
13283        //  storage in the device data environment, all of the original storage
13284        //  must have corresponding storage in the device data environment.
13285        //
13286        if (DerivedType->isAnyPointerType()) {
13287          if (CI == CE || SI == SE) {
13288            SemaRef.Diag(
13289                DerivedLoc,
13290                diag::err_omp_pointer_mapped_along_with_derived_section)
13291                << DerivedLoc;
13292            SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
13293                << RE->getSourceRange();
13294            return true;
13295          }
13296          if (CI->getAssociatedExpression()->getStmtClass() !=
13297                         SI->getAssociatedExpression()->getStmtClass() ||
13298                     CI->getAssociatedDeclaration()->getCanonicalDecl() ==
13299                         SI->getAssociatedDeclaration()->getCanonicalDecl()) {
13300            assert(CI != CE && SI != SE);
13301            SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
13302                << DerivedLoc;
13303            SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
13304                << RE->getSourceRange();
13305            return true;
13306          }
13307        }
13308
13309        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
13310        //  List items of map clauses in the same construct must not share
13311        //  original storage.
13312        //
13313        // An expression is a subset of the other.
13314        if (CurrentRegionOnly && (CI == CE || SI == SE)) {
13315          if (CKind == OMPC_map) {
13316            if (CI != CE || SI != SE) {
13317              // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
13318              // a pointer.
13319              auto Begin =
13320                  CI != CE ? CurComponents.begin() : StackComponents.begin();
13321              auto End = CI != CE ? CurComponents.end() : StackComponents.end();
13322              auto It = Begin;
13323              while (It != End && !It->getAssociatedDeclaration())
13324                std::advance(It, 1);
13325               (0) . __assert_fail ("It != End && \"Expected at least one component with the declaration.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13326, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(It != End &&
13326 (0) . __assert_fail ("It != End && \"Expected at least one component with the declaration.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13326, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">                     "Expected at least one component with the declaration.");
13327              if (It != Begin && It->getAssociatedDeclaration()
13328                                     ->getType()
13329                                     .getCanonicalType()
13330                                     ->isAnyPointerType()) {
13331                IsEnclosedByDataEnvironmentExpr = false;
13332                EnclosingExpr = nullptr;
13333                return false;
13334              }
13335            }
13336            SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
13337          } else {
13338            assert(CKind == OMPC_to || CKind == OMPC_from);
13339            SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
13340                << ERange;
13341          }
13342          SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
13343              << RE->getSourceRange();
13344          return true;
13345        }
13346
13347        // The current expression uses the same base as other expression in the
13348        // data environment but does not contain it completely.
13349        if (!CurrentRegionOnly && SI != SE)
13350          EnclosingExpr = RE;
13351
13352        // The current expression is a subset of the expression in the data
13353        // environment.
13354        IsEnclosedByDataEnvironmentExpr |=
13355            (!CurrentRegionOnly && CI != CE && SI == SE);
13356
13357        return false;
13358      });
13359
13360  if (CurrentRegionOnly)
13361    return FoundError;
13362
13363  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
13364  //  If any part of the original storage of a list item has corresponding
13365  //  storage in the device data environment, all of the original storage must
13366  //  have corresponding storage in the device data environment.
13367  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
13368  //  If a list item is an element of a structure, and a different element of
13369  //  the structure has a corresponding list item in the device data environment
13370  //  prior to a task encountering the construct associated with the map clause,
13371  //  then the list item must also have a corresponding list item in the device
13372  //  data environment prior to the task encountering the construct.
13373  //
13374  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
13375    SemaRef.Diag(ELoc,
13376                 diag::err_omp_original_storage_is_shared_and_does_not_contain)
13377        << ERange;
13378    SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
13379        << EnclosingExpr->getSourceRange();
13380    return true;
13381  }
13382
13383  return FoundError;
13384}
13385
13386// Look up the user-defined mapper given the mapper name and mapped type, and
13387// build a reference to it.
13388static ExprResult buildUserDefinedMapperRef(Sema &SemaRefScope *S,
13389                                            CXXScopeSpec &MapperIdScopeSpec,
13390                                            const DeclarationNameInfo &MapperId,
13391                                            QualType Type,
13392                                            Expr *UnresolvedMapper) {
13393  if (MapperIdScopeSpec.isInvalid())
13394    return ExprError();
13395  // Find all user-defined mappers with the given MapperId.
13396  SmallVector<UnresolvedSet<8>, 4Lookups;
13397  LookupResult Lookup(SemaRefMapperIdSema::LookupOMPMapperName);
13398  Lookup.suppressDiagnostics();
13399  if (S) {
13400    while (S && SemaRef.LookupParsedName(LookupS, &MapperIdScopeSpec)) {
13401      NamedDecl *D = Lookup.getRepresentativeDecl();
13402      while (S && !S->isDeclScope(D))
13403        S = S->getParent();
13404      if (S)
13405        S = S->getParent();
13406      Lookups.emplace_back();
13407      Lookups.back().append(Lookup.begin(), Lookup.end());
13408      Lookup.clear();
13409    }
13410  } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
13411    // Extract the user-defined mappers with the given MapperId.
13412    Lookups.push_back(UnresolvedSet<8>());
13413    for (NamedDecl *D : ULE->decls()) {
13414      auto *DMD = cast<OMPDeclareMapperDecl>(D);
13415       (0) . __assert_fail ("DMD && \"Expect valid OMPDeclareMapperDecl during instantiation.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13415, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
13416      Lookups.back().addDecl(DMD);
13417    }
13418  }
13419  // Defer the lookup for dependent types. The results will be passed through
13420  // UnresolvedMapper on instantiation.
13421  if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
13422      Type->isInstantiationDependentType() ||
13423      Type->containsUnexpandedParameterPack() ||
13424      filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
13425        return !D->isInvalidDecl() &&
13426               (D->getType()->isDependentType() ||
13427                D->getType()->isInstantiationDependentType() ||
13428                D->getType()->containsUnexpandedParameterPack());
13429      })) {
13430    UnresolvedSet<8URS;
13431    for (const UnresolvedSet<8> &Set : Lookups) {
13432      if (Set.empty())
13433        continue;
13434      URS.append(Set.begin(), Set.end());
13435    }
13436    return UnresolvedLookupExpr::Create(
13437        SemaRef.Context/*NamingClass=*/nullptr,
13438        MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
13439        /*ADL=*/false/*Overloaded=*/trueURS.begin(), URS.end());
13440  }
13441  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
13442  //  The type must be of struct, union or class type in C and C++
13443  if (!Type->isStructureOrClassType() && !Type->isUnionType())
13444    return ExprEmpty();
13445  SourceLocation Loc = MapperId.getLoc();
13446  // Perform argument dependent lookup.
13447  if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
13448    argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
13449  // Return the first user-defined mapper with the desired type.
13450  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13451          Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
13452            if (!D->isInvalidDecl() &&
13453                SemaRef.Context.hasSameType(D->getType(), Type))
13454              return D;
13455            return nullptr;
13456          }))
13457    return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
13458  // Find the first user-defined mapper with a type derived from the desired
13459  // type.
13460  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13461          Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
13462            if (!D->isInvalidDecl() &&
13463                SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
13464                !Type.isMoreQualifiedThan(D->getType()))
13465              return D;
13466            return nullptr;
13467          })) {
13468    CXXBasePaths Paths(/*FindAmbiguities=*/true/*RecordPaths=*/true,
13469                       /*DetectVirtual=*/false);
13470    if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
13471      if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
13472              VD->getType().getUnqualifiedType()))) {
13473        if (SemaRef.CheckBaseClassAccess(
13474                Loc, VD->getType(), Type, Paths.front(),
13475                /*DiagID=*/0) != Sema::AR_inaccessible) {
13476          return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
13477        }
13478      }
13479    }
13480  }
13481  // Report error if a mapper is specified, but cannot be found.
13482  if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
13483    SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
13484        << Type << MapperId.getName();
13485    return ExprError();
13486  }
13487  return ExprEmpty();
13488}
13489
13490namespace {
13491// Utility struct that gathers all the related lists associated with a mappable
13492// expression.
13493struct MappableVarListInfo {
13494  // The list of expressions.
13495  ArrayRef<Expr *> VarList;
13496  // The list of processed expressions.
13497  SmallVector<Expr *, 16ProcessedVarList;
13498  // The mappble components for each expression.
13499  OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
13500  // The base declaration of the variable.
13501  SmallVector<ValueDecl *, 16VarBaseDeclarations;
13502  // The reference to the user-defined mapper associated with every expression.
13503  SmallVector<Expr *, 16UDMapperList;
13504
13505  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
13506    // We have a list of components and base declarations for each entry in the
13507    // variable list.
13508    VarComponents.reserve(VarList.size());
13509    VarBaseDeclarations.reserve(VarList.size());
13510  }
13511};
13512}
13513
13514// Check the validity of the provided variable list for the provided clause kind
13515// \a CKind. In the check process the valid expressions, mappable expression
13516// components, variables, and user-defined mappers are extracted and used to
13517// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
13518// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
13519// and \a MapperId are expected to be valid if the clause kind is 'map'.
13520static void checkMappableExpressionList(
13521    Sema &SemaRefDSAStackTy *DSASOpenMPClauseKind CKind,
13522    MappableVarListInfo &MVLISourceLocation StartLoc,
13523    CXXScopeSpec &MapperIdScopeSpecDeclarationNameInfo MapperId,
13524    ArrayRef<Expr *> UnresolvedMappers,
13525    OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
13526    bool IsMapTypeImplicit = false) {
13527  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
13528   (0) . __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13529, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
13529 (0) . __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13529, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Unexpected clause kind with mappable expressions!");
13530
13531  // If the identifier of user-defined mapper is not specified, it is "default".
13532  // We do not change the actual name in this clause to distinguish whether a
13533  // mapper is specified explicitly, i.e., it is not explicitly specified when
13534  // MapperId.getName() is empty.
13535  if (!MapperId.getName() || MapperId.getName().isEmpty()) {
13536    auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
13537    MapperId.setName(DeclNames.getIdentifier(
13538        &SemaRef.getASTContext().Idents.get("default")));
13539  }
13540
13541  // Iterators to find the current unresolved mapper expression.
13542  auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
13543  bool UpdateUMIt = false;
13544  Expr *UnresolvedMapper = nullptr;
13545
13546  // Keep track of the mappable components and base declarations in this clause.
13547  // Each entry in the list is going to have a list of components associated. We
13548  // record each set of the components so that we can build the clause later on.
13549  // In the end we should have the same amount of declarations and component
13550  // lists.
13551
13552  for (Expr *RE : MVLI.VarList) {
13553     (0) . __assert_fail ("RE && \"Null expr in omp to/from/map clause\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13553, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RE && "Null expr in omp to/from/map clause");
13554    SourceLocation ELoc = RE->getExprLoc();
13555
13556    // Find the current unresolved mapper expression.
13557    if (UpdateUMIt && UMIt != UMEnd) {
13558      UMIt++;
13559       (0) . __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13561, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(
13560 (0) . __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13561, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">          UMIt != UMEnd &&
13561 (0) . __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13561, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">          "Expect the size of UnresolvedMappers to match with that of VarList");
13562    }
13563    UpdateUMIt = true;
13564    if (UMIt != UMEnd)
13565      UnresolvedMapper = *UMIt;
13566
13567    const Expr *VE = RE->IgnoreParenLValueCasts();
13568
13569    if (VE->isValueDependent() || VE->isTypeDependent() ||
13570        VE->isInstantiationDependent() ||
13571        VE->containsUnexpandedParameterPack()) {
13572      // Try to find the associated user-defined mapper.
13573      ExprResult ER = buildUserDefinedMapperRef(
13574          SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
13575          VE->getType().getCanonicalType(), UnresolvedMapper);
13576      if (ER.isInvalid())
13577        continue;
13578      MVLI.UDMapperList.push_back(ER.get());
13579      // We can only analyze this information once the missing information is
13580      // resolved.
13581      MVLI.ProcessedVarList.push_back(RE);
13582      continue;
13583    }
13584
13585    Expr *SimpleExpr = RE->IgnoreParenCasts();
13586
13587    if (!RE->IgnoreParenImpCasts()->isLValue()) {
13588      SemaRef.Diag(ELoc,
13589                   diag::err_omp_expected_named_var_member_or_array_expression)
13590          << RE->getSourceRange();
13591      continue;
13592    }
13593
13594    OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
13595    ValueDecl *CurDeclaration = nullptr;
13596
13597    // Obtain the array or member expression bases if required. Also, fill the
13598    // components array with all the components identified in the process.
13599    const Expr *BE = checkMapClauseExpressionBase(
13600        SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
13601    if (!BE)
13602      continue;
13603
13604     (0) . __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13605, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!CurComponents.empty() &&
13605 (0) . __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13605, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Invalid mappable expression information.");
13606
13607    if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
13608      // Add store "this" pointer to class in DSAStackTy for future checking
13609      DSAS->addMappedClassesQualTypes(TE->getType());
13610      // Try to find the associated user-defined mapper.
13611      ExprResult ER = buildUserDefinedMapperRef(
13612          SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
13613          VE->getType().getCanonicalType(), UnresolvedMapper);
13614      if (ER.isInvalid())
13615        continue;
13616      MVLI.UDMapperList.push_back(ER.get());
13617      // Skip restriction checking for variable or field declarations
13618      MVLI.ProcessedVarList.push_back(RE);
13619      MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13620      MVLI.VarComponents.back().append(CurComponents.begin(),
13621                                       CurComponents.end());
13622      MVLI.VarBaseDeclarations.push_back(nullptr);
13623      continue;
13624    }
13625
13626    // For the following checks, we rely on the base declaration which is
13627    // expected to be associated with the last component. The declaration is
13628    // expected to be a variable or a field (if 'this' is being mapped).
13629    CurDeclaration = CurComponents.back().getAssociatedDeclaration();
13630     (0) . __assert_fail ("CurDeclaration && \"Null decl on map clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13630, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CurDeclaration && "Null decl on map clause.");
13631     (0) . __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13633, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(
13632 (0) . __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13633, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">        CurDeclaration->isCanonicalDecl() &&
13633 (0) . __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13633, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">        "Expecting components to have associated only canonical declarations.");
13634
13635    auto *VD = dyn_cast<VarDecl>(CurDeclaration);
13636    const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
13637
13638     (0) . __assert_fail ("(VD || FD) && \"Only variables or fields are expected here!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13638, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((VD || FD) && "Only variables or fields are expected here!");
13639    (void)FD;
13640
13641    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
13642    // threadprivate variables cannot appear in a map clause.
13643    // OpenMP 4.5 [2.10.5, target update Construct]
13644    // threadprivate variables cannot appear in a from clause.
13645    if (VD && DSAS->isThreadPrivate(VD)) {
13646      DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
13647      SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
13648          << getOpenMPClauseName(CKind);
13649      reportOriginalDsa(SemaRef, DSAS, VD, DVar);
13650      continue;
13651    }
13652
13653    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
13654    //  A list item cannot appear in both a map clause and a data-sharing
13655    //  attribute clause on the same construct.
13656
13657    // Check conflicts with other map clause expressions. We check the conflicts
13658    // with the current construct separately from the enclosing data
13659    // environment, because the restrictions are different. We only have to
13660    // check conflicts across regions for the map clauses.
13661    if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
13662                          /*CurrentRegionOnly=*/true, CurComponents, CKind))
13663      break;
13664    if (CKind == OMPC_map &&
13665        checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
13666                          /*CurrentRegionOnly=*/false, CurComponents, CKind))
13667      break;
13668
13669    // OpenMP 4.5 [2.10.5, target update Construct]
13670    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
13671    //  If the type of a list item is a reference to a type T then the type will
13672    //  be considered to be T for all purposes of this clause.
13673    auto I = llvm::find_if(
13674        CurComponents,
13675        [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
13676          return MC.getAssociatedDeclaration();
13677        });
13678     (0) . __assert_fail ("I != CurComponents.end() && \"Null decl on map clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13678, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(I != CurComponents.end() && "Null decl on map clause.");
13679    QualType Type =
13680        I->getAssociatedDeclaration()->getType().getNonReferenceType();
13681
13682    // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
13683    // A list item in a to or from clause must have a mappable type.
13684    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
13685    //  A list item must have a mappable type.
13686    if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
13687                           DSAS, Type))
13688      continue;
13689
13690    if (CKind == OMPC_map) {
13691      // target enter data
13692      // OpenMP [2.10.2, Restrictions, p. 99]
13693      // A map-type must be specified in all map clauses and must be either
13694      // to or alloc.
13695      OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
13696      if (DKind == OMPD_target_enter_data &&
13697          !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
13698        SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13699            << (IsMapTypeImplicit ? 1 : 0)
13700            << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
13701            << getOpenMPDirectiveName(DKind);
13702        continue;
13703      }
13704
13705      // target exit_data
13706      // OpenMP [2.10.3, Restrictions, p. 102]
13707      // A map-type must be specified in all map clauses and must be either
13708      // from, release, or delete.
13709      if (DKind == OMPD_target_exit_data &&
13710          !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
13711            MapType == OMPC_MAP_delete)) {
13712        SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13713            << (IsMapTypeImplicit ? 1 : 0)
13714            << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
13715            << getOpenMPDirectiveName(DKind);
13716        continue;
13717      }
13718
13719      // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13720      // A list item cannot appear in both a map clause and a data-sharing
13721      // attribute clause on the same construct
13722      if (VD && isOpenMPTargetExecutionDirective(DKind)) {
13723        DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
13724        if (isOpenMPPrivate(DVar.CKind)) {
13725          SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13726              << getOpenMPClauseName(DVar.CKind)
13727              << getOpenMPClauseName(OMPC_map)
13728              << getOpenMPDirectiveName(DSAS->getCurrentDirective());
13729          reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
13730          continue;
13731        }
13732      }
13733    }
13734
13735    // Try to find the associated user-defined mapper.
13736    ExprResult ER = buildUserDefinedMapperRef(
13737        SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
13738        Type.getCanonicalType(), UnresolvedMapper);
13739    if (ER.isInvalid())
13740      continue;
13741    MVLI.UDMapperList.push_back(ER.get());
13742
13743    // Save the current expression.
13744    MVLI.ProcessedVarList.push_back(RE);
13745
13746    // Store the components in the stack so that they can be used to check
13747    // against other clauses later on.
13748    DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
13749                                          /*WhereFoundClauseKind=*/OMPC_map);
13750
13751    // Save the components and declaration to create the clause. For purposes of
13752    // the clause creation, any component list that has has base 'this' uses
13753    // null as base declaration.
13754    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13755    MVLI.VarComponents.back().append(CurComponents.begin(),
13756                                     CurComponents.end());
13757    MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
13758                                                           : CurDeclaration);
13759  }
13760}
13761
13762OMPClause *Sema::ActOnOpenMPMapClause(
13763    ArrayRef<OpenMPMapModifierKindMapTypeModifiers,
13764    ArrayRef<SourceLocationMapTypeModifiersLoc,
13765    CXXScopeSpec &MapperIdScopeSpecDeclarationNameInfo &MapperId,
13766    OpenMPMapClauseKind MapTypebool IsMapTypeImplicitSourceLocation MapLoc,
13767    SourceLocation ColonLocArrayRef<Expr *> VarList,
13768    const OMPVarListLocTy &LocsArrayRef<Expr *> UnresolvedMappers) {
13769  OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown,
13770                                       OMPC_MAP_MODIFIER_unknown,
13771                                       OMPC_MAP_MODIFIER_unknown};
13772  SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers];
13773
13774  // Process map-type-modifiers, flag errors for duplicate modifiers.
13775  unsigned Count = 0;
13776  for (unsigned I = 0E = MapTypeModifiers.size(); I < E; ++I) {
13777    if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
13778        llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
13779      Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
13780      continue;
13781    }
13782     (0) . __assert_fail ("Count < OMPMapClause..NumberOfModifiers && \"Modifiers exceed the allowed number of map type modifiers\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13783, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Count < OMPMapClause::NumberOfModifiers &&
13783 (0) . __assert_fail ("Count < OMPMapClause..NumberOfModifiers && \"Modifiers exceed the allowed number of map type modifiers\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 13783, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Modifiers exceed the allowed number of map type modifiers");
13784    Modifiers[Count] = MapTypeModifiers[I];
13785    ModifiersLoc[Count] = MapTypeModifiersLoc[I];
13786    ++Count;
13787  }
13788
13789  MappableVarListInfo MVLI(VarList);
13790  checkMappableExpressionList(*thisDSAStack, OMPC_map, MVLI, Locs.StartLoc,
13791                              MapperIdScopeSpec, MapperId, UnresolvedMappers,
13792                              MapType, IsMapTypeImplicit);
13793
13794  // We need to produce a map clause even if we don't have variables so that
13795  // other diagnostics related with non-existing map clauses are accurate.
13796  return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
13797                              MVLI.VarBaseDeclarations, MVLI.VarComponents,
13798                              MVLI.UDMapperList, Modifiers, ModifiersLoc,
13799                              MapperIdScopeSpec.getWithLocInContext(Context),
13800                              MapperId, MapType, IsMapTypeImplicit, MapLoc);
13801}
13802
13803QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
13804                                               TypeResult ParsedType) {
13805  assert(ParsedType.isUsable());
13806
13807  QualType ReductionType = GetTypeFromParser(ParsedType.get());
13808  if (ReductionType.isNull())
13809    return QualType();
13810
13811  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
13812  // A type name in a declare reduction directive cannot be a function type, an
13813  // array type, a reference type, or a type qualified with const, volatile or
13814  // restrict.
13815  if (ReductionType.hasQualifiers()) {
13816    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
13817    return QualType();
13818  }
13819
13820  if (ReductionType->isFunctionType()) {
13821    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
13822    return QualType();
13823  }
13824  if (ReductionType->isReferenceType()) {
13825    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
13826    return QualType();
13827  }
13828  if (ReductionType->isArrayType()) {
13829    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
13830    return QualType();
13831  }
13832  return ReductionType;
13833}
13834
13835Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
13836    Scope *SDeclContext *DCDeclarationName Name,
13837    ArrayRef<std::pair<QualTypeSourceLocation>> ReductionTypes,
13838    AccessSpecifier ASDecl *PrevDeclInScope) {
13839  SmallVector<Decl *, 8Decls;
13840  Decls.reserve(ReductionTypes.size());
13841
13842  LookupResult Lookup(*thisNameSourceLocation(), LookupOMPReductionName,
13843                      forRedeclarationInCurContext());
13844  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
13845  // A reduction-identifier may not be re-declared in the current scope for the
13846  // same type or for a type that is compatible according to the base language
13847  // rules.
13848  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
13849  OMPDeclareReductionDecl *PrevDRD = nullptr;
13850  bool InCompoundScope = true;
13851  if (S != nullptr) {
13852    // Find previous declaration with the same name not referenced in other
13853    // declarations.
13854    FunctionScopeInfo *ParentFn = getEnclosingFunction();
13855    InCompoundScope =
13856        (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
13857    LookupName(LookupS);
13858    FilterLookupForScope(LookupDCS/*ConsiderLinkage=*/false,
13859                         /*AllowInlineNamespace=*/false);
13860    llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
13861    LookupResult::Filter Filter = Lookup.makeFilter();
13862    while (Filter.hasNext()) {
13863      auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
13864      if (InCompoundScope) {
13865        auto I = UsedAsPrevious.find(PrevDecl);
13866        if (I == UsedAsPrevious.end())
13867          UsedAsPrevious[PrevDecl] = false;
13868        if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
13869          UsedAsPrevious[D] = true;
13870      }
13871      PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
13872          PrevDecl->getLocation();
13873    }
13874    Filter.done();
13875    if (InCompoundScope) {
13876      for (const auto &PrevData : UsedAsPrevious) {
13877        if (!PrevData.second) {
13878          PrevDRD = PrevData.first;
13879          break;
13880        }
13881      }
13882    }
13883  } else if (PrevDeclInScope != nullptr) {
13884    auto *PrevDRDInScope = PrevDRD =
13885        cast<OMPDeclareReductionDecl>(PrevDeclInScope);
13886    do {
13887      PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
13888          PrevDRDInScope->getLocation();
13889      PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
13890    } while (PrevDRDInScope != nullptr);
13891  }
13892  for (const auto &TyData : ReductionTypes) {
13893    const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
13894    bool Invalid = false;
13895    if (I != PreviousRedeclTypes.end()) {
13896      Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
13897          << TyData.first;
13898      Diag(I->second, diag::note_previous_definition);
13899      Invalid = true;
13900    }
13901    PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
13902    auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
13903                                                Name, TyData.first, PrevDRD);
13904    DC->addDecl(DRD);
13905    DRD->setAccess(AS);
13906    Decls.push_back(DRD);
13907    if (Invalid)
13908      DRD->setInvalidDecl();
13909    else
13910      PrevDRD = DRD;
13911  }
13912
13913  return DeclGroupPtrTy::make(
13914      DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
13915}
13916
13917void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *SDecl *D) {
13918  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13919
13920  // Enter new function scope.
13921  PushFunctionScope();
13922  setFunctionHasBranchProtectedScope();
13923  getCurFunction()->setHasOMPDeclareReductionCombiner();
13924
13925  if (S != nullptr)
13926    PushDeclContext(S, DRD);
13927  else
13928    CurContext = DRD;
13929
13930  PushExpressionEvaluationContext(
13931      ExpressionEvaluationContext::PotentiallyEvaluated);
13932
13933  QualType ReductionType = DRD->getType();
13934  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
13935  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
13936  // uses semantics of argument handles by value, but it should be passed by
13937  // reference. C lang does not support references, so pass all parameters as
13938  // pointers.
13939  // Create 'T omp_in;' variable.
13940  VarDecl *OmpInParm =
13941      buildVarDecl(*thisD->getLocation(), ReductionType"omp_in");
13942  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
13943  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
13944  // uses semantics of argument handles by value, but it should be passed by
13945  // reference. C lang does not support references, so pass all parameters as
13946  // pointers.
13947  // Create 'T omp_out;' variable.
13948  VarDecl *OmpOutParm =
13949      buildVarDecl(*thisD->getLocation(), ReductionType"omp_out");
13950  if (S != nullptr) {
13951    PushOnScopeChains(OmpInParmS);
13952    PushOnScopeChains(OmpOutParmS);
13953  } else {
13954    DRD->addDecl(OmpInParm);
13955    DRD->addDecl(OmpOutParm);
13956  }
13957  Expr *InE =
13958      ::buildDeclRefExpr(*thisOmpInParmReductionTypeD->getLocation());
13959  Expr *OutE =
13960      ::buildDeclRefExpr(*thisOmpOutParmReductionTypeD->getLocation());
13961  DRD->setCombinerData(InE, OutE);
13962}
13963
13964void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *DExpr *Combiner) {
13965  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13966  DiscardCleanupsInEvaluationContext();
13967  PopExpressionEvaluationContext();
13968
13969  PopDeclContext();
13970  PopFunctionScopeInfo();
13971
13972  if (Combiner != nullptr)
13973    DRD->setCombiner(Combiner);
13974  else
13975    DRD->setInvalidDecl();
13976}
13977
13978VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *SDecl *D) {
13979  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13980
13981  // Enter new function scope.
13982  PushFunctionScope();
13983  setFunctionHasBranchProtectedScope();
13984
13985  if (S != nullptr)
13986    PushDeclContext(S, DRD);
13987  else
13988    CurContext = DRD;
13989
13990  PushExpressionEvaluationContext(
13991      ExpressionEvaluationContext::PotentiallyEvaluated);
13992
13993  QualType ReductionType = DRD->getType();
13994  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
13995  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
13996  // uses semantics of argument handles by value, but it should be passed by
13997  // reference. C lang does not support references, so pass all parameters as
13998  // pointers.
13999  // Create 'T omp_priv;' variable.
14000  VarDecl *OmpPrivParm =
14001      buildVarDecl(*thisD->getLocation(), ReductionType"omp_priv");
14002  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
14003  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
14004  // uses semantics of argument handles by value, but it should be passed by
14005  // reference. C lang does not support references, so pass all parameters as
14006  // pointers.
14007  // Create 'T omp_orig;' variable.
14008  VarDecl *OmpOrigParm =
14009      buildVarDecl(*thisD->getLocation(), ReductionType"omp_orig");
14010  if (S != nullptr) {
14011    PushOnScopeChains(OmpPrivParmS);
14012    PushOnScopeChains(OmpOrigParmS);
14013  } else {
14014    DRD->addDecl(OmpPrivParm);
14015    DRD->addDecl(OmpOrigParm);
14016  }
14017  Expr *OrigE =
14018      ::buildDeclRefExpr(*thisOmpOrigParmReductionTypeD->getLocation());
14019  Expr *PrivE =
14020      ::buildDeclRefExpr(*thisOmpPrivParmReductionTypeD->getLocation());
14021  DRD->setInitializerData(OrigE, PrivE);
14022  return OmpPrivParm;
14023}
14024
14025void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *DExpr *Initializer,
14026                                                     VarDecl *OmpPrivParm) {
14027  auto *DRD = cast<OMPDeclareReductionDecl>(D);
14028  DiscardCleanupsInEvaluationContext();
14029  PopExpressionEvaluationContext();
14030
14031  PopDeclContext();
14032  PopFunctionScopeInfo();
14033
14034  if (Initializer != nullptr) {
14035    DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
14036  } else if (OmpPrivParm->hasInit()) {
14037    DRD->setInitializer(OmpPrivParm->getInit(),
14038                        OmpPrivParm->isDirectInit()
14039                            ? OMPDeclareReductionDecl::DirectInit
14040                            : OMPDeclareReductionDecl::CopyInit);
14041  } else {
14042    DRD->setInvalidDecl();
14043  }
14044}
14045
14046Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
14047    Scope *SDeclGroupPtrTy DeclReductionsbool IsValid) {
14048  for (Decl *D : DeclReductions.get()) {
14049    if (IsValid) {
14050      if (S)
14051        PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
14052                          /*AddToContext=*/false);
14053    } else {
14054      D->setInvalidDecl();
14055    }
14056  }
14057  return DeclReductions;
14058}
14059
14060TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *SDeclarator &D) {
14061  TypeSourceInfo *TInfo = GetTypeForDeclarator(DS);
14062  QualType T = TInfo->getType();
14063  if (D.isInvalidType())
14064    return true;
14065
14066  if (getLangOpts().CPlusPlus) {
14067    // Check that there are no default arguments (C++ only).
14068    CheckExtraCXXDefaultArguments(D);
14069  }
14070
14071  return CreateParsedType(TTInfo);
14072}
14073
14074QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
14075                                            TypeResult ParsedType) {
14076   (0) . __assert_fail ("ParsedType.isUsable() && \"Expect usable parsed mapper type\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14076, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
14077
14078  QualType MapperType = GetTypeFromParser(ParsedType.get());
14079   (0) . __assert_fail ("!MapperType.isNull() && \"Expect valid mapper type\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14079, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!MapperType.isNull() && "Expect valid mapper type");
14080
14081  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
14082  //  The type must be of struct, union or class type in C and C++
14083  if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
14084    Diag(TyLoc, diag::err_omp_mapper_wrong_type);
14085    return QualType();
14086  }
14087  return MapperType;
14088}
14089
14090OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
14091    Scope *SDeclContext *DCDeclarationName NameQualType MapperType,
14092    SourceLocation StartLocDeclarationName VNAccessSpecifier AS,
14093    Decl *PrevDeclInScope) {
14094  LookupResult Lookup(*thisNameSourceLocation(), LookupOMPMapperName,
14095                      forRedeclarationInCurContext());
14096  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
14097  //  A mapper-identifier may not be redeclared in the current scope for the
14098  //  same type or for a type that is compatible according to the base language
14099  //  rules.
14100  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
14101  OMPDeclareMapperDecl *PrevDMD = nullptr;
14102  bool InCompoundScope = true;
14103  if (S != nullptr) {
14104    // Find previous declaration with the same name not referenced in other
14105    // declarations.
14106    FunctionScopeInfo *ParentFn = getEnclosingFunction();
14107    InCompoundScope =
14108        (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
14109    LookupName(LookupS);
14110    FilterLookupForScope(LookupDCS/*ConsiderLinkage=*/false,
14111                         /*AllowInlineNamespace=*/false);
14112    llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
14113    LookupResult::Filter Filter = Lookup.makeFilter();
14114    while (Filter.hasNext()) {
14115      auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
14116      if (InCompoundScope) {
14117        auto I = UsedAsPrevious.find(PrevDecl);
14118        if (I == UsedAsPrevious.end())
14119          UsedAsPrevious[PrevDecl] = false;
14120        if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
14121          UsedAsPrevious[D] = true;
14122      }
14123      PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
14124          PrevDecl->getLocation();
14125    }
14126    Filter.done();
14127    if (InCompoundScope) {
14128      for (const auto &PrevData : UsedAsPrevious) {
14129        if (!PrevData.second) {
14130          PrevDMD = PrevData.first;
14131          break;
14132        }
14133      }
14134    }
14135  } else if (PrevDeclInScope) {
14136    auto *PrevDMDInScope = PrevDMD =
14137        cast<OMPDeclareMapperDecl>(PrevDeclInScope);
14138    do {
14139      PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
14140          PrevDMDInScope->getLocation();
14141      PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
14142    } while (PrevDMDInScope != nullptr);
14143  }
14144  const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
14145  bool Invalid = false;
14146  if (I != PreviousRedeclTypes.end()) {
14147    Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
14148        << MapperType << Name;
14149    Diag(I->second, diag::note_previous_definition);
14150    Invalid = true;
14151  }
14152  auto *DMD = OMPDeclareMapperDecl::Create(ContextDCStartLocName,
14153                                           MapperTypeVNPrevDMD);
14154  DC->addDecl(DMD);
14155  DMD->setAccess(AS);
14156  if (Invalid)
14157    DMD->setInvalidDecl();
14158
14159  // Enter new function scope.
14160  PushFunctionScope();
14161  setFunctionHasBranchProtectedScope();
14162
14163  CurContext = DMD;
14164
14165  return DMD;
14166}
14167
14168void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
14169                                                    Scope *S,
14170                                                    QualType MapperType,
14171                                                    SourceLocation StartLoc,
14172                                                    DeclarationName VN) {
14173  VarDecl *VD = buildVarDecl(*thisStartLocMapperTypeVN.getAsString());
14174  if (S)
14175    PushOnScopeChains(VDS);
14176  else
14177    DMD->addDecl(VD);
14178  Expr *MapperVarRefExpr = buildDeclRefExpr(*thisVDMapperTypeStartLoc);
14179  DMD->setMapperVarRef(MapperVarRefExpr);
14180}
14181
14182Sema::DeclGroupPtrTy
14183Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *DScope *S,
14184                                           ArrayRef<OMPClause *> ClauseList) {
14185  PopDeclContext();
14186  PopFunctionScopeInfo();
14187
14188  if (D) {
14189    if (S)
14190      PushOnScopeChains(DS/*AddToContext=*/false);
14191    D->CreateClauses(Context, ClauseList);
14192  }
14193
14194  return DeclGroupPtrTy::make(DeclGroupRef(D));
14195}
14196
14197OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
14198                                           SourceLocation StartLoc,
14199                                           SourceLocation LParenLoc,
14200                                           SourceLocation EndLoc) {
14201  Expr *ValExpr = NumTeams;
14202  Stmt *HelperValStmt = nullptr;
14203
14204  // OpenMP [teams Constrcut, Restrictions]
14205  // The num_teams expression must evaluate to a positive integer value.
14206  if (!isNonNegativeIntegerValue(ValExpr*thisOMPC_num_teams,
14207                                 /*StrictlyPositive=*/true))
14208    return nullptr;
14209
14210  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14211  OpenMPDirectiveKind CaptureRegion =
14212      getOpenMPCaptureRegionForClause(DKindOMPC_num_teams);
14213  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14214    ValExpr = MakeFullExpr(ValExpr).get();
14215    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14216    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14217    HelperValStmt = buildPreInits(Context, Captures);
14218  }
14219
14220  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
14221                                         StartLoc, LParenLoc, EndLoc);
14222}
14223
14224OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
14225                                              SourceLocation StartLoc,
14226                                              SourceLocation LParenLoc,
14227                                              SourceLocation EndLoc) {
14228  Expr *ValExpr = ThreadLimit;
14229  Stmt *HelperValStmt = nullptr;
14230
14231  // OpenMP [teams Constrcut, Restrictions]
14232  // The thread_limit expression must evaluate to a positive integer value.
14233  if (!isNonNegativeIntegerValue(ValExpr*thisOMPC_thread_limit,
14234                                 /*StrictlyPositive=*/true))
14235    return nullptr;
14236
14237  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14238  OpenMPDirectiveKind CaptureRegion =
14239      getOpenMPCaptureRegionForClause(DKindOMPC_thread_limit);
14240  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14241    ValExpr = MakeFullExpr(ValExpr).get();
14242    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14243    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14244    HelperValStmt = buildPreInits(Context, Captures);
14245  }
14246
14247  return new (Context) OMPThreadLimitClause(
14248      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
14249}
14250
14251OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
14252                                           SourceLocation StartLoc,
14253                                           SourceLocation LParenLoc,
14254                                           SourceLocation EndLoc) {
14255  Expr *ValExpr = Priority;
14256
14257  // OpenMP [2.9.1, task Constrcut]
14258  // The priority-value is a non-negative numerical scalar expression.
14259  if (!isNonNegativeIntegerValue(ValExpr*thisOMPC_priority,
14260                                 /*StrictlyPositive=*/false))
14261    return nullptr;
14262
14263  return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
14264}
14265
14266OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
14267                                            SourceLocation StartLoc,
14268                                            SourceLocation LParenLoc,
14269                                            SourceLocation EndLoc) {
14270  Expr *ValExpr = Grainsize;
14271
14272  // OpenMP [2.9.2, taskloop Constrcut]
14273  // The parameter of the grainsize clause must be a positive integer
14274  // expression.
14275  if (!isNonNegativeIntegerValue(ValExpr*thisOMPC_grainsize,
14276                                 /*StrictlyPositive=*/true))
14277    return nullptr;
14278
14279  return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
14280}
14281
14282OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
14283                                           SourceLocation StartLoc,
14284                                           SourceLocation LParenLoc,
14285                                           SourceLocation EndLoc) {
14286  Expr *ValExpr = NumTasks;
14287
14288  // OpenMP [2.9.2, taskloop Constrcut]
14289  // The parameter of the num_tasks clause must be a positive integer
14290  // expression.
14291  if (!isNonNegativeIntegerValue(ValExpr*thisOMPC_num_tasks,
14292                                 /*StrictlyPositive=*/true))
14293    return nullptr;
14294
14295  return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
14296}
14297
14298OMPClause *Sema::ActOnOpenMPHintClause(Expr *HintSourceLocation StartLoc,
14299                                       SourceLocation LParenLoc,
14300                                       SourceLocation EndLoc) {
14301  // OpenMP [2.13.2, critical construct, Description]
14302  // ... where hint-expression is an integer constant expression that evaluates
14303  // to a valid lock hint.
14304  ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(HintOMPC_hint);
14305  if (HintExpr.isInvalid())
14306    return nullptr;
14307  return new (Context)
14308      OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
14309}
14310
14311OMPClause *Sema::ActOnOpenMPDistScheduleClause(
14312    OpenMPDistScheduleClauseKind KindExpr *ChunkSizeSourceLocation StartLoc,
14313    SourceLocation LParenLocSourceLocation KindLocSourceLocation CommaLoc,
14314    SourceLocation EndLoc) {
14315  if (Kind == OMPC_DIST_SCHEDULE_unknown) {
14316    std::string Values;
14317    Values += "'";
14318    Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule0);
14319    Values += "'";
14320    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14321        << Values << getOpenMPClauseName(OMPC_dist_schedule);
14322    return nullptr;
14323  }
14324  Expr *ValExpr = ChunkSize;
14325  Stmt *HelperValStmt = nullptr;
14326  if (ChunkSize) {
14327    if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
14328        !ChunkSize->isInstantiationDependent() &&
14329        !ChunkSize->containsUnexpandedParameterPack()) {
14330      SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
14331      ExprResult Val =
14332          PerformOpenMPImplicitIntegerConversion(ChunkSizeLocChunkSize);
14333      if (Val.isInvalid())
14334        return nullptr;
14335
14336      ValExpr = Val.get();
14337
14338      // OpenMP [2.7.1, Restrictions]
14339      //  chunk_size must be a loop invariant integer expression with a positive
14340      //  value.
14341      llvm::APSInt Result;
14342      if (ValExpr->isIntegerConstantExpr(Result, Context)) {
14343        if (Result.isSigned() && !Result.isStrictlyPositive()) {
14344          Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14345              << "dist_schedule" << ChunkSize->getSourceRange();
14346          return nullptr;
14347        }
14348      } else if (getOpenMPCaptureRegionForClause(
14349                     DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
14350                     OMPD_unknown &&
14351                 !CurContext->isDependentContext()) {
14352        ValExpr = MakeFullExpr(ValExpr).get();
14353        llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14354        ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14355        HelperValStmt = buildPreInits(Context, Captures);
14356      }
14357    }
14358  }
14359
14360  return new (Context)
14361      OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
14362                            Kind, ValExpr, HelperValStmt);
14363}
14364
14365OMPClause *Sema::ActOnOpenMPDefaultmapClause(
14366    OpenMPDefaultmapClauseModifier MOpenMPDefaultmapClauseKind Kind,
14367    SourceLocation StartLocSourceLocation LParenLocSourceLocation MLoc,
14368    SourceLocation KindLocSourceLocation EndLoc) {
14369  // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
14370  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
14371    std::string Value;
14372    SourceLocation Loc;
14373    Value += "'";
14374    if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
14375      Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
14376                                             OMPC_DEFAULTMAP_MODIFIER_tofrom);
14377      Loc = MLoc;
14378    } else {
14379      Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
14380                                             OMPC_DEFAULTMAP_scalar);
14381      Loc = KindLoc;
14382    }
14383    Value += "'";
14384    Diag(Loc, diag::err_omp_unexpected_clause_value)
14385        << Value << getOpenMPClauseName(OMPC_defaultmap);
14386    return nullptr;
14387  }
14388  DSAStack->setDefaultDMAToFromScalar(StartLoc);
14389
14390  return new (Context)
14391      OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
14392}
14393
14394bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
14395  DeclContext *CurLexicalContext = getCurLexicalContext();
14396  if (!CurLexicalContext->isFileContext() &&
14397      !CurLexicalContext->isExternCContext() &&
14398      !CurLexicalContext->isExternCXXContext() &&
14399      !isa<CXXRecordDecl>(CurLexicalContext) &&
14400      !isa<ClassTemplateDecl>(CurLexicalContext) &&
14401      !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
14402      !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
14403    Diag(Loc, diag::err_omp_region_not_file_context);
14404    return false;
14405  }
14406  ++DeclareTargetNestingLevel;
14407  return true;
14408}
14409
14410void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
14411   (0) . __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14412, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DeclareTargetNestingLevel > 0 &&
14412 (0) . __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14412, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">         "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
14413  --DeclareTargetNestingLevel;
14414}
14415
14416void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope,
14417                                        CXXScopeSpec &ScopeSpec,
14418                                        const DeclarationNameInfo &Id,
14419                                        OMPDeclareTargetDeclAttr::MapTypeTy MT,
14420                                        NamedDeclSetType &SameDirectiveDecls) {
14421  LookupResult Lookup(*thisIdLookupOrdinaryName);
14422  LookupParsedName(LookupCurScope, &ScopeSpectrue);
14423
14424  if (Lookup.isAmbiguous())
14425    return;
14426  Lookup.suppressDiagnostics();
14427
14428  if (!Lookup.isSingleResult()) {
14429    VarOrFuncDeclFilterCCC CCC(*this);
14430    if (TypoCorrection Corrected =
14431            CorrectTypo(IdLookupOrdinaryNameCurScopenullptrCCC,
14432                        CTK_ErrorRecovery)) {
14433      diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
14434                                  << Id.getName());
14435      checkDeclIsAllowedInOpenMPTarget(nullptrCorrected.getCorrectionDecl());
14436      return;
14437    }
14438
14439    Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
14440    return;
14441  }
14442
14443  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
14444  if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
14445      isa<FunctionTemplateDecl>(ND)) {
14446    if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
14447      Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
14448    llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
14449        OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
14450            cast<ValueDecl>(ND));
14451    if (!Res) {
14452      auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
14453      ND->addAttr(A);
14454      if (ASTMutationListener *ML = Context.getASTMutationListener())
14455        ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
14456      checkDeclIsAllowedInOpenMPTarget(nullptrNDId.getLoc());
14457    } else if (*Res != MT) {
14458      Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
14459          << Id.getName();
14460    }
14461  } else {
14462    Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
14463  }
14464}
14465
14466static void checkDeclInTargetContext(SourceLocation SLSourceRange SR,
14467                                     Sema &SemaRefDecl *D) {
14468  if (!D || !isa<VarDecl>(D))
14469    return;
14470  auto *VD = cast<VarDecl>(D);
14471  if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
14472    return;
14473  SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
14474  SemaRef.Diag(SL, diag::note_used_here) << SR;
14475}
14476
14477static bool checkValueDeclInTarget(SourceLocation SLSourceRange SR,
14478                                   Sema &SemaRefDSAStackTy *Stack,
14479                                   ValueDecl *VD) {
14480  return VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
14481         checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
14482                           /*FullCheck=*/false);
14483}
14484
14485void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *EDecl *D,
14486                                            SourceLocation IdLoc) {
14487  if (!D || D->isInvalidDecl())
14488    return;
14489  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
14490  SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
14491  if (auto *VD = dyn_cast<VarDecl>(D)) {
14492    // Only global variables can be marked as declare target.
14493    if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
14494        !VD->isStaticDataMember())
14495      return;
14496    // 2.10.6: threadprivate variable cannot appear in a declare target
14497    // directive.
14498    if (DSAStack->isThreadPrivate(VD)) {
14499      Diag(SL, diag::err_omp_threadprivate_in_target);
14500      reportOriginalDsa(*thisDSAStack, VD, DSAStack->getTopDSA(VD, false));
14501      return;
14502    }
14503  }
14504  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
14505    D = FTD->getTemplatedDecl();
14506  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
14507    llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
14508        OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
14509    if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
14510       (0) . __assert_fail ("IdLoc.isValid() && \"Source location is expected\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14510, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(IdLoc.isValid() && "Source location is expected");
14511      Diag(IdLoc, diag::err_omp_function_in_link_clause);
14512      Diag(FD->getLocation(), diag::note_defined_here) << FD;
14513      return;
14514    }
14515  }
14516  if (auto *VD = dyn_cast<ValueDecl>(D)) {
14517    // Problem if any with var declared with incomplete type will be reported
14518    // as normal, so no need to check it here.
14519    if ((E || !VD->getType()->isIncompleteType()) &&
14520        !checkValueDeclInTarget(SL, SR, *thisDSAStack, VD))
14521      return;
14522    if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
14523      // Checking declaration inside declare target region.
14524      if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
14525          isa<FunctionTemplateDecl>(D)) {
14526        auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
14527            Context, OMPDeclareTargetDeclAttr::MT_To);
14528        D->addAttr(A);
14529        if (ASTMutationListener *ML = Context.getASTMutationListener())
14530          ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
14531      }
14532      return;
14533    }
14534  }
14535  if (!E)
14536    return;
14537  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *thisD);
14538}
14539
14540OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
14541                                     CXXScopeSpec &MapperIdScopeSpec,
14542                                     DeclarationNameInfo &MapperId,
14543                                     const OMPVarListLocTy &Locs,
14544                                     ArrayRef<Expr *> UnresolvedMappers) {
14545  MappableVarListInfo MVLI(VarList);
14546  checkMappableExpressionList(*thisDSAStack, OMPC_to, MVLI, Locs.StartLoc,
14547                              MapperIdScopeSpec, MapperId, UnresolvedMappers);
14548  if (MVLI.ProcessedVarList.empty())
14549    return nullptr;
14550
14551  return OMPToClause::Create(
14552      Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
14553      MVLI.VarComponents, MVLI.UDMapperList,
14554      MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
14555}
14556
14557OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
14558                                       CXXScopeSpec &MapperIdScopeSpec,
14559                                       DeclarationNameInfo &MapperId,
14560                                       const OMPVarListLocTy &Locs,
14561                                       ArrayRef<Expr *> UnresolvedMappers) {
14562  MappableVarListInfo MVLI(VarList);
14563  checkMappableExpressionList(*thisDSAStack, OMPC_from, MVLI, Locs.StartLoc,
14564                              MapperIdScopeSpec, MapperId, UnresolvedMappers);
14565  if (MVLI.ProcessedVarList.empty())
14566    return nullptr;
14567
14568  return OMPFromClause::Create(
14569      Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
14570      MVLI.VarComponents, MVLI.UDMapperList,
14571      MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
14572}
14573
14574OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
14575                                               const OMPVarListLocTy &Locs) {
14576  MappableVarListInfo MVLI(VarList);
14577  SmallVector<Expr *, 8PrivateCopies;
14578  SmallVector<Expr *, 8Inits;
14579
14580  for (Expr *RefExpr : VarList) {
14581     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_ptr clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14581, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
14582    SourceLocation ELoc;
14583    SourceRange ERange;
14584    Expr *SimpleRefExpr = RefExpr;
14585    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14586    if (Res.second) {
14587      // It will be analyzed later.
14588      MVLI.ProcessedVarList.push_back(RefExpr);
14589      PrivateCopies.push_back(nullptr);
14590      Inits.push_back(nullptr);
14591    }
14592    ValueDecl *D = Res.first;
14593    if (!D)
14594      continue;
14595
14596    QualType Type = D->getType();
14597    Type = Type.getNonReferenceType().getUnqualifiedType();
14598
14599    auto *VD = dyn_cast<VarDecl>(D);
14600
14601    // Item should be a pointer or reference to pointer.
14602    if (!Type->isPointerType()) {
14603      Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
14604          << 0 << RefExpr->getSourceRange();
14605      continue;
14606    }
14607
14608    // Build the private variable and the expression that refers to it.
14609    auto VDPrivate =
14610        buildVarDecl(*this, ELoc, Type, D->getName(),
14611                     D->hasAttrs() ? &D->getAttrs() : nullptr,
14612                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14613    if (VDPrivate->isInvalidDecl())
14614      continue;
14615
14616    CurContext->addDecl(VDPrivate);
14617    DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14618        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
14619
14620    // Add temporary variable to initialize the private copy of the pointer.
14621    VarDecl *VDInit =
14622        buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
14623    DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
14624        *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
14625    AddInitializerToDecl(VDPrivate,
14626                         DefaultLvalueConversion(VDInitRefExpr).get(),
14627                         /*DirectInit=*/false);
14628
14629    // If required, build a capture to implement the privatization initialized
14630    // with the current list item value.
14631    DeclRefExpr *Ref = nullptr;
14632    if (!VD)
14633      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14634    MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
14635    PrivateCopies.push_back(VDPrivateRefExpr);
14636    Inits.push_back(VDInitRefExpr);
14637
14638    // We need to add a data sharing attribute for this variable to make sure it
14639    // is correctly captured. A variable that shows up in a use_device_ptr has
14640    // similar properties of a first private variable.
14641    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14642
14643    // Create a mappable component for the list item. List items in this clause
14644    // only need a component.
14645    MVLI.VarBaseDeclarations.push_back(D);
14646    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
14647    MVLI.VarComponents.back().push_back(
14648        OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
14649  }
14650
14651  if (MVLI.ProcessedVarList.empty())
14652    return nullptr;
14653
14654  return OMPUseDevicePtrClause::Create(
14655      Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
14656      MVLI.VarBaseDeclarations, MVLI.VarComponents);
14657}
14658
14659OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
14660                                              const OMPVarListLocTy &Locs) {
14661  MappableVarListInfo MVLI(VarList);
14662  for (Expr *RefExpr : VarList) {
14663     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP is_device_ptr clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14663, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
14664    SourceLocation ELoc;
14665    SourceRange ERange;
14666    Expr *SimpleRefExpr = RefExpr;
14667    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14668    if (Res.second) {
14669      // It will be analyzed later.
14670      MVLI.ProcessedVarList.push_back(RefExpr);
14671    }
14672    ValueDecl *D = Res.first;
14673    if (!D)
14674      continue;
14675
14676    QualType Type = D->getType();
14677    // item should be a pointer or array or reference to pointer or array
14678    if (!Type.getNonReferenceType()->isPointerType() &&
14679        !Type.getNonReferenceType()->isArrayType()) {
14680      Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
14681          << 0 << RefExpr->getSourceRange();
14682      continue;
14683    }
14684
14685    // Check if the declaration in the clause does not show up in any data
14686    // sharing attribute.
14687    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14688    if (isOpenMPPrivate(DVar.CKind)) {
14689      Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14690          << getOpenMPClauseName(DVar.CKind)
14691          << getOpenMPClauseName(OMPC_is_device_ptr)
14692          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14693      reportOriginalDsa(*thisDSAStack, D, DVar);
14694      continue;
14695    }
14696
14697    const Expr *ConflictExpr;
14698    if (DSAStack->checkMappableExprComponentListsForDecl(
14699            D, /*CurrentRegionOnly=*/true,
14700            [&ConflictExpr](
14701                OMPClauseMappableExprCommon::MappableExprComponentListRef R,
14702                OpenMPClauseKind) -> bool {
14703              ConflictExpr = R.front().getAssociatedExpression();
14704              return true;
14705            })) {
14706      Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
14707      Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
14708          << ConflictExpr->getSourceRange();
14709      continue;
14710    }
14711
14712    // Store the components in the stack so that they can be used to check
14713    // against other clauses later on.
14714    OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
14715    DSAStack->addMappableExpressionComponents(
14716        D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
14717
14718    // Record the expression we've just processed.
14719    MVLI.ProcessedVarList.push_back(SimpleRefExpr);
14720
14721    // Create a mappable component for the list item. List items in this clause
14722    // only need a component. We use a null declaration to signal fields in
14723    // 'this'.
14724     (0) . __assert_fail ("(isa(SimpleRefExpr) || isa(cast(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14726, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((isa<DeclRefExpr>(SimpleRefExpr) ||
14725 (0) . __assert_fail ("(isa(SimpleRefExpr) || isa(cast(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14726, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">            isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
14726 (0) . __assert_fail ("(isa(SimpleRefExpr) || isa(cast(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14726, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">           "Unexpected device pointer expression!");
14727    MVLI.VarBaseDeclarations.push_back(
14728        isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
14729    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
14730    MVLI.VarComponents.back().push_back(MC);
14731  }
14732
14733  if (MVLI.ProcessedVarList.empty())
14734    return nullptr;
14735
14736  return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
14737                                      MVLI.VarBaseDeclarations,
14738                                      MVLI.VarComponents);
14739}
14740
14741OMPClause *Sema::ActOnOpenMPAllocateClause(
14742    Expr *AllocatorArrayRef<Expr *> VarListSourceLocation StartLoc,
14743    SourceLocation ColonLocSourceLocation LParenLocSourceLocation EndLoc) {
14744  if (Allocator) {
14745    // OpenMP [2.11.4 allocate Clause, Description]
14746    // allocator is an expression of omp_allocator_handle_t type.
14747    if (!findOMPAllocatorHandleT(*thisAllocator->getExprLoc(), DSAStack))
14748      return nullptr;
14749
14750    ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
14751    if (AllocatorRes.isInvalid())
14752      return nullptr;
14753    AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
14754                                             DSAStack->getOMPAllocatorHandleT(),
14755                                             Sema::AA_Initializing,
14756                                             /*AllowExplicit=*/true);
14757    if (AllocatorRes.isInvalid())
14758      return nullptr;
14759    Allocator = AllocatorRes.get();
14760  }
14761  // Analyze and build list of variables.
14762  SmallVector<Expr *, 8Vars;
14763  for (Expr *RefExpr : VarList) {
14764     (0) . __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaOpenMP.cpp", 14764, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RefExpr && "NULL expr in OpenMP private clause.");
14765    SourceLocation ELoc;
14766    SourceRange ERange;
14767    Expr *SimpleRefExpr = RefExpr;
14768    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14769    if (Res.second) {
14770      // It will be analyzed later.
14771      Vars.push_back(RefExpr);
14772    }
14773    ValueDecl *D = Res.first;
14774    if (!D)
14775      continue;
14776
14777    auto *VD = dyn_cast<VarDecl>(D);
14778    DeclRefExpr *Ref = nullptr;
14779    if (!VD && !CurContext->isDependentContext())
14780      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14781    Vars.push_back((VD || CurContext->isDependentContext())
14782                       ? RefExpr->IgnoreParens()
14783                       : Ref);
14784  }
14785
14786  if (Vars.empty())
14787    return nullptr;
14788
14789  return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
14790                                   ColonLoc, EndLoc, Vars);
14791}
14792
clang::Sema::InitDataSharingAttributesStack
clang::Sema::pushOpenMPFunctionRegion
clang::Sema::popOpenMPFunctionRegion
clang::Sema::diagIfOpenMPDeviceCode
clang::Sema::checkOpenMPDeviceFunction
clang::Sema::checkOpenMPDeviceExpr
clang::Sema::isOpenMPCapturedByRef
clang::Sema::getOpenMPNestingLevel
clang::Sema::isInOpenMPTargetExecutionDirective
clang::Sema::isOpenMPCapturedDecl
clang::Sema::adjustOpenMPTargetScopeIndex
clang::Sema::startOpenMPLoop
clang::Sema::isOpenMPPrivateDecl
clang::Sema::setOpenMPCaptureKind
clang::Sema::isOpenMPTargetCapturedDecl
clang::Sema::DestroyDataSharingAttributesStack
clang::Sema::StartOpenMPDSABlock
clang::Sema::StartOpenMPClause
clang::Sema::EndOpenMPClause
clang::Sema::EndOpenMPDSABlock
clang::Sema::ActOnOpenMPIdExpression
clang::Sema::ActOnOpenMPThreadprivateDirective
clang::Sema::CheckOMPThreadPrivateDecl
clang::Sema::ActOnOpenMPAllocateDirective
clang::Sema::ActOnOpenMPRequiresDirective
clang::Sema::CheckOMPRequiresDecl
clang::Sema::ActOnOpenMPRegionStart
clang::Sema::getOpenMPCaptureLevels
clang::Sema::ActOnOpenMPRegionEnd
clang::Sema::ActOnOpenMPExecutableDirective
clang::Sema::ActOnOpenMPDeclareSimdDirective
clang::Sema::ActOnOpenMPParallelDirective
clang::Sema::ActOnOpenMPLoopInitialization
clang::Sema::ActOnOpenMPSimdDirective
clang::Sema::ActOnOpenMPForDirective
clang::Sema::ActOnOpenMPForSimdDirective
clang::Sema::ActOnOpenMPSectionsDirective
clang::Sema::ActOnOpenMPSectionDirective
clang::Sema::ActOnOpenMPSingleDirective
clang::Sema::ActOnOpenMPMasterDirective
clang::Sema::ActOnOpenMPCriticalDirective
clang::Sema::ActOnOpenMPParallelForDirective
clang::Sema::ActOnOpenMPParallelForSimdDirective
clang::Sema::ActOnOpenMPParallelSectionsDirective
clang::Sema::ActOnOpenMPTaskDirective
clang::Sema::ActOnOpenMPTaskyieldDirective
clang::Sema::ActOnOpenMPBarrierDirective
clang::Sema::ActOnOpenMPTaskwaitDirective
clang::Sema::ActOnOpenMPTaskgroupDirective
clang::Sema::ActOnOpenMPFlushDirective
clang::Sema::ActOnOpenMPOrderedDirective
clang::Sema::ActOnOpenMPAtomicDirective
clang::Sema::ActOnOpenMPTargetDirective
clang::Sema::ActOnOpenMPTargetParallelDirective
clang::Sema::ActOnOpenMPTargetParallelForDirective
clang::Sema::ActOnOpenMPTargetDataDirective
clang::Sema::ActOnOpenMPTargetEnterDataDirective
clang::Sema::ActOnOpenMPTargetExitDataDirective
clang::Sema::ActOnOpenMPTargetUpdateDirective
clang::Sema::ActOnOpenMPTeamsDirective
clang::Sema::ActOnOpenMPCancellationPointDirective
clang::Sema::ActOnOpenMPCancelDirective
clang::Sema::ActOnOpenMPTaskLoopDirective
clang::Sema::ActOnOpenMPTaskLoopSimdDirective
clang::Sema::ActOnOpenMPDistributeDirective
clang::Sema::ActOnOpenMPDistributeParallelForDirective
clang::Sema::ActOnOpenMPDistributeParallelForSimdDirective
clang::Sema::ActOnOpenMPDistributeSimdDirective
clang::Sema::ActOnOpenMPTargetParallelForSimdDirective
clang::Sema::ActOnOpenMPTargetSimdDirective
clang::Sema::ActOnOpenMPTeamsDistributeDirective
clang::Sema::ActOnOpenMPTeamsDistributeSimdDirective
clang::Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective
clang::Sema::ActOnOpenMPTeamsDistributeParallelForDirective
clang::Sema::ActOnOpenMPTargetTeamsDirective
clang::Sema::ActOnOpenMPTargetTeamsDistributeDirective
clang::Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective
clang::Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective
clang::Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective
clang::Sema::ActOnOpenMPSingleExprClause
clang::Sema::ActOnOpenMPIfClause
clang::Sema::ActOnOpenMPFinalClause
clang::Sema::PerformOpenMPImplicitIntegerConversion
clang::Sema::ActOnOpenMPNumThreadsClause
clang::Sema::VerifyPositiveIntegerConstantInClause
clang::Sema::ActOnOpenMPSafelenClause
clang::Sema::ActOnOpenMPSimdlenClause
clang::Sema::ActOnOpenMPAllocatorClause
clang::Sema::ActOnOpenMPCollapseClause
clang::Sema::ActOnOpenMPOrderedClause
clang::Sema::ActOnOpenMPSimpleClause
clang::Sema::ActOnOpenMPDefaultClause
clang::Sema::ActOnOpenMPProcBindClause
clang::Sema::ActOnOpenMPAtomicDefaultMemOrderClause
clang::Sema::ActOnOpenMPSingleExprWithArgClause
clang::Sema::ActOnOpenMPScheduleClause
clang::Sema::ActOnOpenMPClause
clang::Sema::ActOnOpenMPNowaitClause
clang::Sema::ActOnOpenMPUntiedClause
clang::Sema::ActOnOpenMPMergeableClause
clang::Sema::ActOnOpenMPReadClause
clang::Sema::ActOnOpenMPWriteClause
clang::Sema::ActOnOpenMPUpdateClause
clang::Sema::ActOnOpenMPCaptureClause
clang::Sema::ActOnOpenMPSeqCstClause
clang::Sema::ActOnOpenMPThreadsClause
clang::Sema::ActOnOpenMPSIMDClause
clang::Sema::ActOnOpenMPNogroupClause
clang::Sema::ActOnOpenMPUnifiedAddressClause
clang::Sema::ActOnOpenMPUnifiedSharedMemoryClause
clang::Sema::ActOnOpenMPReverseOffloadClause
clang::Sema::ActOnOpenMPDynamicAllocatorsClause
clang::Sema::ActOnOpenMPVarListClause
clang::Sema::getOpenMPCapturedExpr
clang::Sema::ActOnOpenMPPrivateClause
clang::Sema::ActOnOpenMPFirstprivateClause
clang::Sema::ActOnOpenMPLastprivateClause
clang::Sema::ActOnOpenMPSharedClause
clang::Sema::ActOnOpenMPReductionClause
clang::Sema::ActOnOpenMPTaskReductionClause
clang::Sema::ActOnOpenMPInReductionClause
clang::Sema::CheckOpenMPLinearModifier
clang::Sema::CheckOpenMPLinearDecl
clang::Sema::ActOnOpenMPLinearClause
clang::Sema::ActOnOpenMPAlignedClause
clang::Sema::ActOnOpenMPCopyinClause
clang::Sema::ActOnOpenMPCopyprivateClause
clang::Sema::ActOnOpenMPFlushClause
clang::Sema::ActOnOpenMPDependClause
clang::Sema::ActOnOpenMPDeviceClause
clang::Sema::ActOnOpenMPMapClause
clang::Sema::ActOnOpenMPDeclareReductionType
clang::Sema::ActOnOpenMPDeclareReductionDirectiveStart
clang::Sema::ActOnOpenMPDeclareReductionCombinerStart
clang::Sema::ActOnOpenMPDeclareReductionCombinerEnd
clang::Sema::ActOnOpenMPDeclareReductionInitializerStart
clang::Sema::ActOnOpenMPDeclareReductionInitializerEnd
clang::Sema::ActOnOpenMPDeclareReductionDirectiveEnd
clang::Sema::ActOnOpenMPDeclareMapperVarDecl
clang::Sema::ActOnOpenMPDeclareMapperType
clang::Sema::ActOnOpenMPDeclareMapperDirectiveStart
clang::Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl
clang::Sema::ActOnOpenMPDeclareMapperDirectiveEnd
clang::Sema::ActOnOpenMPNumTeamsClause
clang::Sema::ActOnOpenMPThreadLimitClause
clang::Sema::ActOnOpenMPPriorityClause
clang::Sema::ActOnOpenMPGrainsizeClause
clang::Sema::ActOnOpenMPNumTasksClause
clang::Sema::ActOnOpenMPHintClause
clang::Sema::ActOnOpenMPDistScheduleClause
clang::Sema::ActOnOpenMPDefaultmapClause
clang::Sema::ActOnStartOpenMPDeclareTargetDirective
clang::Sema::ActOnFinishOpenMPDeclareTargetDirective
clang::Sema::ActOnOpenMPDeclareTargetName
clang::Sema::checkDeclIsAllowedInOpenMPTarget
clang::Sema::ActOnOpenMPToClause
clang::Sema::ActOnOpenMPFromClause
clang::Sema::ActOnOpenMPUseDevicePtrClause
clang::Sema::ActOnOpenMPIsDevicePtrClause
clang::Sema::ActOnOpenMPAllocateClause