Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
Line
Count
Source (jump to first uncovered line)
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/OpenMPClause.h"
22
#include "clang/AST/StmtCXX.h"
23
#include "clang/AST/StmtOpenMP.h"
24
#include "clang/AST/StmtVisitor.h"
25
#include "clang/AST/TypeOrdering.h"
26
#include "clang/Basic/DiagnosticSema.h"
27
#include "clang/Basic/OpenMPKinds.h"
28
#include "clang/Basic/PartialDiagnostic.h"
29
#include "clang/Basic/TargetInfo.h"
30
#include "clang/Sema/EnterExpressionEvaluationContext.h"
31
#include "clang/Sema/Initialization.h"
32
#include "clang/Sema/Lookup.h"
33
#include "clang/Sema/ParsedAttr.h"
34
#include "clang/Sema/Scope.h"
35
#include "clang/Sema/ScopeInfo.h"
36
#include "clang/Sema/SemaInternal.h"
37
#include "llvm/ADT/IndexedMap.h"
38
#include "llvm/ADT/PointerEmbeddedInt.h"
39
#include "llvm/ADT/STLExtras.h"
40
#include "llvm/ADT/SmallSet.h"
41
#include "llvm/ADT/StringExtras.h"
42
#include "llvm/Frontend/OpenMP/OMPAssume.h"
43
#include "llvm/Frontend/OpenMP/OMPConstants.h"
44
#include <optional>
45
#include <set>
46
47
using namespace clang;
48
using namespace llvm::omp;
49
50
//===----------------------------------------------------------------------===//
51
// Stack of data-sharing attributes for variables
52
//===----------------------------------------------------------------------===//
53
54
static const Expr *checkMapClauseExpressionBase(
55
    Sema &SemaRef, Expr *E,
56
    OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
57
    OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
58
59
namespace {
60
/// Default data sharing attributes, which can be applied to directive.
61
enum DefaultDataSharingAttributes {
62
  DSA_unspecified = 0,       /// Data sharing attribute not specified.
63
  DSA_none = 1 << 0,         /// Default data sharing attribute 'none'.
64
  DSA_shared = 1 << 1,       /// Default data sharing attribute 'shared'.
65
  DSA_private = 1 << 2,      /// Default data sharing attribute 'private'.
66
  DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
67
};
68
69
/// Stack for tracking declarations used in OpenMP directives and
70
/// clauses and their data-sharing attributes.
71
class DSAStackTy {
72
public:
73
  struct DSAVarData {
74
    OpenMPDirectiveKind DKind = OMPD_unknown;
75
    OpenMPClauseKind CKind = OMPC_unknown;
76
    unsigned Modifier = 0;
77
    const Expr *RefExpr = nullptr;
78
    DeclRefExpr *PrivateCopy = nullptr;
79
    SourceLocation ImplicitDSALoc;
80
    bool AppliedToPointee = false;
81
0
    DSAVarData() = default;
82
    DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
83
               const Expr *RefExpr, DeclRefExpr *PrivateCopy,
84
               SourceLocation ImplicitDSALoc, unsigned Modifier,
85
               bool AppliedToPointee)
86
        : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
87
          PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
88
0
          AppliedToPointee(AppliedToPointee) {}
89
  };
90
  using OperatorOffsetTy =
91
      llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
92
  using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>;
93
  /// Kind of the declaration used in the uses_allocators clauses.
94
  enum class UsesAllocatorsDeclKind {
95
    /// Predefined allocator
96
    PredefinedAllocator,
97
    /// User-defined allocator
98
    UserDefinedAllocator,
99
    /// The declaration that represent allocator trait
100
    AllocatorTrait,
101
  };
102
103
private:
104
  struct DSAInfo {
105
    OpenMPClauseKind Attributes = OMPC_unknown;
106
    unsigned Modifier = 0;
107
    /// Pointer to a reference expression and a flag which shows that the
108
    /// variable is marked as lastprivate(true) or not (false).
109
    llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
110
    DeclRefExpr *PrivateCopy = nullptr;
111
    /// true if the attribute is applied to the pointee, not the variable
112
    /// itself.
113
    bool AppliedToPointee = false;
114
  };
115
  using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
116
  using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
117
  using LCDeclInfo = std::pair<unsigned, VarDecl *>;
118
  using LoopControlVariablesMapTy =
119
      llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
120
  /// Struct that associates a component with the clause kind where they are
121
  /// found.
122
  struct MappedExprComponentTy {
123
    OMPClauseMappableExprCommon::MappableExprComponentLists Components;
124
    OpenMPClauseKind Kind = OMPC_unknown;
125
  };
126
  using MappedExprComponentsTy =
127
      llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
128
  using CriticalsWithHintsTy =
129
      llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
130
  struct ReductionData {
131
    using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
132
    SourceRange ReductionRange;
133
    llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
134
0
    ReductionData() = default;
135
0
    void set(BinaryOperatorKind BO, SourceRange RR) {
136
0
      ReductionRange = RR;
137
0
      ReductionOp = BO;
138
0
    }
139
0
    void set(const Expr *RefExpr, SourceRange RR) {
140
0
      ReductionRange = RR;
141
0
      ReductionOp = RefExpr;
142
0
    }
143
  };
144
  using DeclReductionMapTy =
145
      llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
146
  struct DefaultmapInfo {
147
    OpenMPDefaultmapClauseModifier ImplicitBehavior =
148
        OMPC_DEFAULTMAP_MODIFIER_unknown;
149
    SourceLocation SLoc;
150
0
    DefaultmapInfo() = default;
151
    DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
152
0
        : ImplicitBehavior(M), SLoc(Loc) {}
153
  };
154
155
  struct SharingMapTy {
156
    DeclSAMapTy SharingMap;
157
    DeclReductionMapTy ReductionMap;
158
    UsedRefMapTy AlignedMap;
159
    UsedRefMapTy NontemporalMap;
160
    MappedExprComponentsTy MappedExprComponents;
161
    LoopControlVariablesMapTy LCVMap;
162
    DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
163
    SourceLocation DefaultAttrLoc;
164
    DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown + 1];
165
    OpenMPDirectiveKind Directive = OMPD_unknown;
166
    /// GenericLoopDirective with bind clause is mapped to other directives,
167
    /// like for, distribute and simd. Presently, set MappedDirective to
168
    /// OMPLoop. This may also be used in a similar way for other constructs.
169
    OpenMPDirectiveKind MappedDirective = OMPD_unknown;
170
    DeclarationNameInfo DirectiveName;
171
    Scope *CurScope = nullptr;
172
    DeclContext *Context = nullptr;
173
    SourceLocation ConstructLoc;
174
    /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
175
    /// get the data (loop counters etc.) about enclosing loop-based construct.
176
    /// This data is required during codegen.
177
    DoacrossClauseMapTy DoacrossDepends;
178
    /// First argument (Expr *) contains optional argument of the
179
    /// 'ordered' clause, the second one is true if the regions has 'ordered'
180
    /// clause, false otherwise.
181
    std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
182
    bool RegionHasOrderConcurrent = false;
183
    unsigned AssociatedLoops = 1;
184
    bool HasMutipleLoops = false;
185
    const Decl *PossiblyLoopCounter = nullptr;
186
    bool NowaitRegion = false;
187
    bool UntiedRegion = false;
188
    bool CancelRegion = false;
189
    bool LoopStart = false;
190
    bool BodyComplete = false;
191
    SourceLocation PrevScanLocation;
192
    SourceLocation PrevOrderedLocation;
193
    SourceLocation InnerTeamsRegionLoc;
194
    /// Reference to the taskgroup task_reduction reference expression.
195
    Expr *TaskgroupReductionRef = nullptr;
196
    llvm::DenseSet<QualType> MappedClassesQualTypes;
197
    SmallVector<Expr *, 4> InnerUsedAllocators;
198
    llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
199
    /// List of globals marked as declare target link in this target region
200
    /// (isOpenMPTargetExecutionDirective(Directive) == true).
201
    llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
202
    /// List of decls used in inclusive/exclusive clauses of the scan directive.
203
    llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
204
    llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
205
        UsesAllocatorsDecls;
206
    /// Data is required on creating capture fields for implicit
207
    /// default first|private clause.
208
    struct ImplicitDefaultFDInfoTy {
209
      /// Field decl.
210
      const FieldDecl *FD = nullptr;
211
      /// Nesting stack level
212
      size_t StackLevel = 0;
213
      /// Capture variable decl.
214
      VarDecl *VD = nullptr;
215
      ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel,
216
                              VarDecl *VD)
217
0
          : FD(FD), StackLevel(StackLevel), VD(VD) {}
218
    };
219
    /// List of captured fields
220
    llvm::SmallVector<ImplicitDefaultFDInfoTy, 8>
221
        ImplicitDefaultFirstprivateFDs;
222
    Expr *DeclareMapperVar = nullptr;
223
    SmallVector<VarDecl *, 16> IteratorVarDecls;
224
    SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
225
                 Scope *CurScope, SourceLocation Loc)
226
        : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
227
0
          ConstructLoc(Loc) {}
228
    SharingMapTy() = default;
229
  };
230
231
  using StackTy = SmallVector<SharingMapTy, 4>;
232
233
  /// Stack of used declaration and their data-sharing attributes.
234
  DeclSAMapTy Threadprivates;
235
  const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
236
  SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
237
  /// true, if check for DSA must be from parent directive, false, if
238
  /// from current directive.
239
  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
240
  Sema &SemaRef;
241
  bool ForceCapturing = false;
242
  /// true if all the variables in the target executable directives must be
243
  /// captured by reference.
244
  bool ForceCaptureByReferenceInTargetExecutable = false;
245
  CriticalsWithHintsTy Criticals;
246
  unsigned IgnoredStackElements = 0;
247
248
  /// Iterators over the stack iterate in order from innermost to outermost
249
  /// directive.
250
  using const_iterator = StackTy::const_reverse_iterator;
251
0
  const_iterator begin() const {
252
0
    return Stack.empty() ? const_iterator()
253
0
                         : Stack.back().first.rbegin() + IgnoredStackElements;
254
0
  }
255
0
  const_iterator end() const {
256
0
    return Stack.empty() ? const_iterator() : Stack.back().first.rend();
257
0
  }
258
  using iterator = StackTy::reverse_iterator;
259
0
  iterator begin() {
260
0
    return Stack.empty() ? iterator()
261
0
                         : Stack.back().first.rbegin() + IgnoredStackElements;
262
0
  }
263
0
  iterator end() {
264
0
    return Stack.empty() ? iterator() : Stack.back().first.rend();
265
0
  }
266
267
  // Convenience operations to get at the elements of the stack.
268
269
0
  bool isStackEmpty() const {
270
0
    return Stack.empty() ||
271
0
           Stack.back().second != CurrentNonCapturingFunctionScope ||
272
0
           Stack.back().first.size() <= IgnoredStackElements;
273
0
  }
274
0
  size_t getStackSize() const {
275
0
    return isStackEmpty() ? 0
276
0
                          : Stack.back().first.size() - IgnoredStackElements;
277
0
  }
278
279
0
  SharingMapTy *getTopOfStackOrNull() {
280
0
    size_t Size = getStackSize();
281
0
    if (Size == 0)
282
0
      return nullptr;
283
0
    return &Stack.back().first[Size - 1];
284
0
  }
285
0
  const SharingMapTy *getTopOfStackOrNull() const {
286
0
    return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
287
0
  }
288
0
  SharingMapTy &getTopOfStack() {
289
0
    assert(!isStackEmpty() && "no current directive");
290
0
    return *getTopOfStackOrNull();
291
0
  }
292
0
  const SharingMapTy &getTopOfStack() const {
293
0
    return const_cast<DSAStackTy &>(*this).getTopOfStack();
294
0
  }
295
296
0
  SharingMapTy *getSecondOnStackOrNull() {
297
0
    size_t Size = getStackSize();
298
0
    if (Size <= 1)
299
0
      return nullptr;
300
0
    return &Stack.back().first[Size - 2];
301
0
  }
302
0
  const SharingMapTy *getSecondOnStackOrNull() const {
303
0
    return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
304
0
  }
305
306
  /// Get the stack element at a certain level (previously returned by
307
  /// \c getNestingLevel).
308
  ///
309
  /// Note that nesting levels count from outermost to innermost, and this is
310
  /// the reverse of our iteration order where new inner levels are pushed at
311
  /// the front of the stack.
312
0
  SharingMapTy &getStackElemAtLevel(unsigned Level) {
313
0
    assert(Level < getStackSize() && "no such stack element");
314
0
    return Stack.back().first[Level];
315
0
  }
316
0
  const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
317
0
    return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
318
0
  }
319
320
  DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
321
322
  /// Checks if the variable is a local for OpenMP region.
323
  bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
324
325
  /// Vector of previously declared requires directives
326
  SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
327
  /// omp_allocator_handle_t type.
328
  QualType OMPAllocatorHandleT;
329
  /// omp_depend_t type.
330
  QualType OMPDependT;
331
  /// omp_event_handle_t type.
332
  QualType OMPEventHandleT;
333
  /// omp_alloctrait_t type.
334
  QualType OMPAlloctraitT;
335
  /// Expression for the predefined allocators.
336
  Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
337
      nullptr};
338
  /// Vector of previously encountered target directives
339
  SmallVector<SourceLocation, 2> TargetLocations;
340
  SourceLocation AtomicLocation;
341
  /// Vector of declare variant construct traits.
342
  SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
343
344
public:
345
46
  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
346
347
  /// Sets omp_allocator_handle_t type.
348
0
  void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
349
  /// Gets omp_allocator_handle_t type.
350
0
  QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
351
  /// Sets omp_alloctrait_t type.
352
0
  void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
353
  /// Gets omp_alloctrait_t type.
354
0
  QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
355
  /// Sets the given default allocator.
356
  void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
357
0
                    Expr *Allocator) {
358
0
    OMPPredefinedAllocators[AllocatorKind] = Allocator;
359
0
  }
360
  /// Returns the specified default allocator.
361
0
  Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
362
0
    return OMPPredefinedAllocators[AllocatorKind];
363
0
  }
364
  /// Sets omp_depend_t type.
365
0
  void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
366
  /// Gets omp_depend_t type.
367
0
  QualType getOMPDependT() const { return OMPDependT; }
368
369
  /// Sets omp_event_handle_t type.
370
0
  void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
371
  /// Gets omp_event_handle_t type.
372
0
  QualType getOMPEventHandleT() const { return OMPEventHandleT; }
373
374
0
  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
375
0
  OpenMPClauseKind getClauseParsingMode() const {
376
0
    assert(isClauseParsingMode() && "Must be in clause parsing mode.");
377
0
    return ClauseKindMode;
378
0
  }
379
0
  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
380
381
0
  bool isBodyComplete() const {
382
0
    const SharingMapTy *Top = getTopOfStackOrNull();
383
0
    return Top && Top->BodyComplete;
384
0
  }
385
0
  void setBodyComplete() { getTopOfStack().BodyComplete = true; }
386
387
0
  bool isForceVarCapturing() const { return ForceCapturing; }
388
0
  void setForceVarCapturing(bool V) { ForceCapturing = V; }
389
390
0
  void setForceCaptureByReferenceInTargetExecutable(bool V) {
391
0
    ForceCaptureByReferenceInTargetExecutable = V;
392
0
  }
393
0
  bool isForceCaptureByReferenceInTargetExecutable() const {
394
0
    return ForceCaptureByReferenceInTargetExecutable;
395
0
  }
396
397
  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
398
0
            Scope *CurScope, SourceLocation Loc) {
399
0
    assert(!IgnoredStackElements &&
400
0
           "cannot change stack while ignoring elements");
401
0
    if (Stack.empty() ||
402
0
        Stack.back().second != CurrentNonCapturingFunctionScope)
403
0
      Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
404
0
    Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
405
0
    Stack.back().first.back().DefaultAttrLoc = Loc;
406
0
  }
407
408
0
  void pop() {
409
0
    assert(!IgnoredStackElements &&
410
0
           "cannot change stack while ignoring elements");
411
0
    assert(!Stack.back().first.empty() &&
412
0
           "Data-sharing attributes stack is empty!");
413
0
    Stack.back().first.pop_back();
414
0
  }
415
416
  /// RAII object to temporarily leave the scope of a directive when we want to
417
  /// logically operate in its parent.
418
  class ParentDirectiveScope {
419
    DSAStackTy &Self;
420
    bool Active;
421
422
  public:
423
    ParentDirectiveScope(DSAStackTy &Self, bool Activate)
424
0
        : Self(Self), Active(false) {
425
0
      if (Activate)
426
0
        enable();
427
0
    }
428
0
    ~ParentDirectiveScope() { disable(); }
429
0
    void disable() {
430
0
      if (Active) {
431
0
        --Self.IgnoredStackElements;
432
0
        Active = false;
433
0
      }
434
0
    }
435
0
    void enable() {
436
0
      if (!Active) {
437
0
        ++Self.IgnoredStackElements;
438
0
        Active = true;
439
0
      }
440
0
    }
441
  };
442
443
  /// Marks that we're started loop parsing.
444
0
  void loopInit() {
445
0
    assert(isOpenMPLoopDirective(getCurrentDirective()) &&
446
0
           "Expected loop-based directive.");
447
0
    getTopOfStack().LoopStart = true;
448
0
  }
449
  /// Start capturing of the variables in the loop context.
450
0
  void loopStart() {
451
0
    assert(isOpenMPLoopDirective(getCurrentDirective()) &&
452
0
           "Expected loop-based directive.");
453
0
    getTopOfStack().LoopStart = false;
454
0
  }
455
  /// true, if variables are captured, false otherwise.
456
0
  bool isLoopStarted() const {
457
0
    assert(isOpenMPLoopDirective(getCurrentDirective()) &&
458
0
           "Expected loop-based directive.");
459
0
    return !getTopOfStack().LoopStart;
460
0
  }
461
  /// Marks (or clears) declaration as possibly loop counter.
462
0
  void resetPossibleLoopCounter(const Decl *D = nullptr) {
463
0
    getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
464
0
  }
465
  /// Gets the possible loop counter decl.
466
0
  const Decl *getPossiblyLoopCunter() const {
467
0
    return getTopOfStack().PossiblyLoopCounter;
468
0
  }
469
  /// Start new OpenMP region stack in new non-capturing function.
470
0
  void pushFunction() {
471
0
    assert(!IgnoredStackElements &&
472
0
           "cannot change stack while ignoring elements");
473
0
    const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
474
0
    assert(!isa<CapturingScopeInfo>(CurFnScope));
475
0
    CurrentNonCapturingFunctionScope = CurFnScope;
476
0
  }
477
  /// Pop region stack for non-capturing function.
478
0
  void popFunction(const FunctionScopeInfo *OldFSI) {
479
0
    assert(!IgnoredStackElements &&
480
0
           "cannot change stack while ignoring elements");
481
0
    if (!Stack.empty() && Stack.back().second == OldFSI) {
482
0
      assert(Stack.back().first.empty());
483
0
      Stack.pop_back();
484
0
    }
485
0
    CurrentNonCapturingFunctionScope = nullptr;
486
0
    for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
487
0
      if (!isa<CapturingScopeInfo>(FSI)) {
488
0
        CurrentNonCapturingFunctionScope = FSI;
489
0
        break;
490
0
      }
491
0
    }
492
0
  }
493
494
0
  void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
495
0
    Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
496
0
  }
497
  const std::pair<const OMPCriticalDirective *, llvm::APSInt>
498
0
  getCriticalWithHint(const DeclarationNameInfo &Name) const {
499
0
    auto I = Criticals.find(Name.getAsString());
500
0
    if (I != Criticals.end())
501
0
      return I->second;
502
0
    return std::make_pair(nullptr, llvm::APSInt());
503
0
  }
504
  /// If 'aligned' declaration for given variable \a D was not seen yet,
505
  /// add it and return NULL; otherwise return previous occurrence's expression
506
  /// for diagnostics.
507
  const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
508
  /// If 'nontemporal' declaration for given variable \a D was not seen yet,
509
  /// add it and return NULL; otherwise return previous occurrence's expression
510
  /// for diagnostics.
511
  const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
512
513
  /// Register specified variable as loop control variable.
514
  void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
515
  /// Check if the specified variable is a loop control variable for
516
  /// current region.
517
  /// \return The index of the loop control variable in the list of associated
518
  /// for-loops (from outer to inner).
519
  const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
520
  /// Check if the specified variable is a loop control variable for
521
  /// parent region.
522
  /// \return The index of the loop control variable in the list of associated
523
  /// for-loops (from outer to inner).
524
  const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
525
  /// Check if the specified variable is a loop control variable for
526
  /// current region.
527
  /// \return The index of the loop control variable in the list of associated
528
  /// for-loops (from outer to inner).
529
  const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
530
                                         unsigned Level) const;
531
  /// Get the loop control variable for the I-th loop (or nullptr) in
532
  /// parent directive.
533
  const ValueDecl *getParentLoopControlVariable(unsigned I) const;
534
535
  /// Marks the specified decl \p D as used in scan directive.
536
0
  void markDeclAsUsedInScanDirective(ValueDecl *D) {
537
0
    if (SharingMapTy *Stack = getSecondOnStackOrNull())
538
0
      Stack->UsedInScanDirective.insert(D);
539
0
  }
540
541
  /// Checks if the specified declaration was used in the inner scan directive.
542
0
  bool isUsedInScanDirective(ValueDecl *D) const {
543
0
    if (const SharingMapTy *Stack = getTopOfStackOrNull())
544
0
      return Stack->UsedInScanDirective.contains(D);
545
0
    return false;
546
0
  }
547
548
  /// Adds explicit data sharing attribute to the specified declaration.
549
  void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
550
              DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
551
              bool AppliedToPointee = false);
552
553
  /// Adds additional information for the reduction items with the reduction id
554
  /// represented as an operator.
555
  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
556
                                 BinaryOperatorKind BOK);
557
  /// Adds additional information for the reduction items with the reduction id
558
  /// represented as reduction identifier.
559
  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
560
                                 const Expr *ReductionRef);
561
  /// Returns the location and reduction operation from the innermost parent
562
  /// region for the given \p D.
563
  const DSAVarData
564
  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
565
                                   BinaryOperatorKind &BOK,
566
                                   Expr *&TaskgroupDescriptor) const;
567
  /// Returns the location and reduction operation from the innermost parent
568
  /// region for the given \p D.
569
  const DSAVarData
570
  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
571
                                   const Expr *&ReductionRef,
572
                                   Expr *&TaskgroupDescriptor) const;
573
  /// Return reduction reference expression for the current taskgroup or
574
  /// parallel/worksharing directives with task reductions.
575
0
  Expr *getTaskgroupReductionRef() const {
576
0
    assert((getTopOfStack().Directive == OMPD_taskgroup ||
577
0
            ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
578
0
              isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
579
0
             !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
580
0
           "taskgroup reference expression requested for non taskgroup or "
581
0
           "parallel/worksharing directive.");
582
0
    return getTopOfStack().TaskgroupReductionRef;
583
0
  }
584
  /// Checks if the given \p VD declaration is actually a taskgroup reduction
585
  /// descriptor variable at the \p Level of OpenMP regions.
586
0
  bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
587
0
    return getStackElemAtLevel(Level).TaskgroupReductionRef &&
588
0
           cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
589
0
                   ->getDecl() == VD;
590
0
  }
591
592
  /// Returns data sharing attributes from top of the stack for the
593
  /// specified declaration.
594
  const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
595
  /// Returns data-sharing attributes for the specified declaration.
596
  const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
597
  /// Returns data-sharing attributes for the specified declaration.
598
  const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
599
  /// Checks if the specified variables has data-sharing attributes which
600
  /// match specified \a CPred predicate in any directive which matches \a DPred
601
  /// predicate.
602
  const DSAVarData
603
  hasDSA(ValueDecl *D,
604
         const llvm::function_ref<bool(OpenMPClauseKind, bool,
605
                                       DefaultDataSharingAttributes)>
606
             CPred,
607
         const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
608
         bool FromParent) const;
609
  /// Checks if the specified variables has data-sharing attributes which
610
  /// match specified \a CPred predicate in any innermost directive which
611
  /// matches \a DPred predicate.
612
  const DSAVarData
613
  hasInnermostDSA(ValueDecl *D,
614
                  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
615
                  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
616
                  bool FromParent) const;
617
  /// Checks if the specified variables has explicit data-sharing
618
  /// attributes which match specified \a CPred predicate at the specified
619
  /// OpenMP region.
620
  bool
621
  hasExplicitDSA(const ValueDecl *D,
622
                 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
623
                 unsigned Level, bool NotLastprivate = false) const;
624
625
  /// Returns true if the directive at level \Level matches in the
626
  /// specified \a DPred predicate.
627
  bool hasExplicitDirective(
628
      const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
629
      unsigned Level) const;
630
631
  /// Finds a directive which matches specified \a DPred predicate.
632
  bool hasDirective(
633
      const llvm::function_ref<bool(
634
          OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
635
          DPred,
636
      bool FromParent) const;
637
638
  /// Returns currently analyzed directive.
639
0
  OpenMPDirectiveKind getCurrentDirective() const {
640
0
    const SharingMapTy *Top = getTopOfStackOrNull();
641
0
    return Top ? Top->Directive : OMPD_unknown;
642
0
  }
643
0
  OpenMPDirectiveKind getMappedDirective() const {
644
0
    const SharingMapTy *Top = getTopOfStackOrNull();
645
0
    return Top ? Top->MappedDirective : OMPD_unknown;
646
0
  }
647
0
  void setCurrentDirective(OpenMPDirectiveKind NewDK) {
648
0
    SharingMapTy *Top = getTopOfStackOrNull();
649
0
    assert(Top &&
650
0
           "Before calling setCurrentDirective Top of Stack not to be NULL.");
651
    // Store the old into MappedDirective & assign argument NewDK to Directive.
652
0
    Top->Directive = NewDK;
653
0
  }
654
0
  void setMappedDirective(OpenMPDirectiveKind NewDK) {
655
0
    SharingMapTy *Top = getTopOfStackOrNull();
656
0
    assert(Top &&
657
0
           "Before calling setMappedDirective Top of Stack not to be NULL.");
658
    // Store the old into MappedDirective & assign argument NewDK to Directive.
659
0
    Top->MappedDirective = NewDK;
660
0
  }
661
  /// Returns directive kind at specified level.
662
0
  OpenMPDirectiveKind getDirective(unsigned Level) const {
663
0
    assert(!isStackEmpty() && "No directive at specified level.");
664
0
    return getStackElemAtLevel(Level).Directive;
665
0
  }
666
  /// Returns the capture region at the specified level.
667
  OpenMPDirectiveKind getCaptureRegion(unsigned Level,
668
0
                                       unsigned OpenMPCaptureLevel) const {
669
0
    SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
670
0
    getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
671
0
    return CaptureRegions[OpenMPCaptureLevel];
672
0
  }
673
  /// Returns parent directive.
674
0
  OpenMPDirectiveKind getParentDirective() const {
675
0
    const SharingMapTy *Parent = getSecondOnStackOrNull();
676
0
    return Parent ? Parent->Directive : OMPD_unknown;
677
0
  }
678
679
  /// Add requires decl to internal vector
680
0
  void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
681
682
  /// Checks if the defined 'requires' directive has specified type of clause.
683
0
  template <typename ClauseType> bool hasRequiresDeclWithClause() const {
684
0
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
0
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
0
        return isa<ClauseType>(C);
687
0
      });
Unexecuted instantiation: SemaOpenMP.cpp:(anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPDynamicAllocatorsClause>() const::{lambda(clang::OMPRequiresDecl const*)#1}::operator()(clang::OMPRequiresDecl const*) const::{lambda(clang::OMPClause const*)#1}::operator()(clang::OMPClause const) const
Unexecuted instantiation: SemaOpenMP.cpp:(anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedSharedMemoryClause>() const::{lambda(clang::OMPRequiresDecl const*)#1}::operator()(clang::OMPRequiresDecl const*) const::{lambda(clang::OMPClause const*)#1}::operator()(clang::OMPClause const) const
Unexecuted instantiation: SemaOpenMP.cpp:(anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedAddressClause>() const::{lambda(clang::OMPRequiresDecl const*)#1}::operator()(clang::OMPRequiresDecl const*) const::{lambda(clang::OMPClause const*)#1}::operator()(clang::OMPClause const) const
Unexecuted instantiation: SemaOpenMP.cpp:(anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPReverseOffloadClause>() const::{lambda(clang::OMPRequiresDecl const*)#1}::operator()(clang::OMPRequiresDecl const*) const::{lambda(clang::OMPClause const*)#1}::operator()(clang::OMPClause const) const
688
0
    });
Unexecuted instantiation: SemaOpenMP.cpp:(anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPDynamicAllocatorsClause>() const::{lambda(clang::OMPRequiresDecl const*)#1}::operator()(clang::OMPRequiresDecl const*) const
Unexecuted instantiation: SemaOpenMP.cpp:(anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedSharedMemoryClause>() const::{lambda(clang::OMPRequiresDecl const*)#1}::operator()(clang::OMPRequiresDecl const*) const
Unexecuted instantiation: SemaOpenMP.cpp:(anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedAddressClause>() const::{lambda(clang::OMPRequiresDecl const*)#1}::operator()(clang::OMPRequiresDecl const*) const
Unexecuted instantiation: SemaOpenMP.cpp:(anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPReverseOffloadClause>() const::{lambda(clang::OMPRequiresDecl const*)#1}::operator()(clang::OMPRequiresDecl const*) const
689
0
  }
Unexecuted instantiation: SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPDynamicAllocatorsClause>() const
Unexecuted instantiation: SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedSharedMemoryClause>() const
Unexecuted instantiation: SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedAddressClause>() const
Unexecuted instantiation: SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPReverseOffloadClause>() const
690
691
  /// Checks for a duplicate clause amongst previously declared requires
692
  /// directives
693
0
  bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
694
0
    bool IsDuplicate = false;
695
0
    for (OMPClause *CNew : ClauseList) {
696
0
      for (const OMPRequiresDecl *D : RequiresDecls) {
697
0
        for (const OMPClause *CPrev : D->clauselists()) {
698
0
          if (CNew->getClauseKind() == CPrev->getClauseKind()) {
699
0
            SemaRef.Diag(CNew->getBeginLoc(),
700
0
                         diag::err_omp_requires_clause_redeclaration)
701
0
                << getOpenMPClauseName(CNew->getClauseKind());
702
0
            SemaRef.Diag(CPrev->getBeginLoc(),
703
0
                         diag::note_omp_requires_previous_clause)
704
0
                << getOpenMPClauseName(CPrev->getClauseKind());
705
0
            IsDuplicate = true;
706
0
          }
707
0
        }
708
0
      }
709
0
    }
710
0
    return IsDuplicate;
711
0
  }
712
713
  /// Add location of previously encountered target to internal vector
714
0
  void addTargetDirLocation(SourceLocation LocStart) {
715
0
    TargetLocations.push_back(LocStart);
716
0
  }
717
718
  /// Add location for the first encountered atomicc directive.
719
0
  void addAtomicDirectiveLoc(SourceLocation Loc) {
720
0
    if (AtomicLocation.isInvalid())
721
0
      AtomicLocation = Loc;
722
0
  }
723
724
  /// Returns the location of the first encountered atomic directive in the
725
  /// module.
726
0
  SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
727
728
  // Return previously encountered target region locations.
729
0
  ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
730
0
    return TargetLocations;
731
0
  }
732
733
  /// Set default data sharing attribute to none.
734
0
  void setDefaultDSANone(SourceLocation Loc) {
735
0
    getTopOfStack().DefaultAttr = DSA_none;
736
0
    getTopOfStack().DefaultAttrLoc = Loc;
737
0
  }
738
  /// Set default data sharing attribute to shared.
739
0
  void setDefaultDSAShared(SourceLocation Loc) {
740
0
    getTopOfStack().DefaultAttr = DSA_shared;
741
0
    getTopOfStack().DefaultAttrLoc = Loc;
742
0
  }
743
  /// Set default data sharing attribute to private.
744
0
  void setDefaultDSAPrivate(SourceLocation Loc) {
745
0
    getTopOfStack().DefaultAttr = DSA_private;
746
0
    getTopOfStack().DefaultAttrLoc = Loc;
747
0
  }
748
  /// Set default data sharing attribute to firstprivate.
749
0
  void setDefaultDSAFirstPrivate(SourceLocation Loc) {
750
0
    getTopOfStack().DefaultAttr = DSA_firstprivate;
751
0
    getTopOfStack().DefaultAttrLoc = Loc;
752
0
  }
753
  /// Set default data mapping attribute to Modifier:Kind
754
  void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
755
0
                         OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
756
0
    DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
757
0
    DMI.ImplicitBehavior = M;
758
0
    DMI.SLoc = Loc;
759
0
  }
760
  /// Check whether the implicit-behavior has been set in defaultmap
761
0
  bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
762
0
    if (VariableCategory == OMPC_DEFAULTMAP_unknown)
763
0
      return getTopOfStack()
764
0
                     .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
765
0
                     .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
766
0
             getTopOfStack()
767
0
                     .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
768
0
                     .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
769
0
             getTopOfStack()
770
0
                     .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
771
0
                     .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
772
0
    return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
773
0
           OMPC_DEFAULTMAP_MODIFIER_unknown;
774
0
  }
775
776
0
  ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
777
0
    return ConstructTraits;
778
0
  }
779
  void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
780
0
                            bool ScopeEntry) {
781
0
    if (ScopeEntry)
782
0
      ConstructTraits.append(Traits.begin(), Traits.end());
783
0
    else
784
0
      for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
785
0
        llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
786
0
        assert(Top == Trait && "Something left a trait on the stack!");
787
0
        (void)Trait;
788
0
        (void)Top;
789
0
      }
790
0
  }
791
792
0
  DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
793
0
    return getStackSize() <= Level ? DSA_unspecified
794
0
                                   : getStackElemAtLevel(Level).DefaultAttr;
795
0
  }
796
0
  DefaultDataSharingAttributes getDefaultDSA() const {
797
0
    return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
798
0
  }
799
0
  SourceLocation getDefaultDSALocation() const {
800
0
    return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
801
0
  }
802
  OpenMPDefaultmapClauseModifier
803
0
  getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
804
0
    return isStackEmpty()
805
0
               ? OMPC_DEFAULTMAP_MODIFIER_unknown
806
0
               : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
807
0
  }
808
  OpenMPDefaultmapClauseModifier
809
  getDefaultmapModifierAtLevel(unsigned Level,
810
0
                               OpenMPDefaultmapClauseKind Kind) const {
811
0
    return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
812
0
  }
813
  bool isDefaultmapCapturedByRef(unsigned Level,
814
0
                                 OpenMPDefaultmapClauseKind Kind) const {
815
0
    OpenMPDefaultmapClauseModifier M =
816
0
        getDefaultmapModifierAtLevel(Level, Kind);
817
0
    if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
818
0
      return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
819
0
             (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
820
0
             (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
821
0
             (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
822
0
    }
823
0
    return true;
824
0
  }
825
  static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
826
0
                                     OpenMPDefaultmapClauseKind Kind) {
827
0
    switch (Kind) {
828
0
    case OMPC_DEFAULTMAP_scalar:
829
0
    case OMPC_DEFAULTMAP_pointer:
830
0
      return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
831
0
             (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
832
0
             (M == OMPC_DEFAULTMAP_MODIFIER_default);
833
0
    case OMPC_DEFAULTMAP_aggregate:
834
0
      return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
835
0
    default:
836
0
      break;
837
0
    }
838
0
    llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
839
0
  }
840
  bool mustBeFirstprivateAtLevel(unsigned Level,
841
0
                                 OpenMPDefaultmapClauseKind Kind) const {
842
0
    OpenMPDefaultmapClauseModifier M =
843
0
        getDefaultmapModifierAtLevel(Level, Kind);
844
0
    return mustBeFirstprivateBase(M, Kind);
845
0
  }
846
0
  bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
847
0
    OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
848
0
    return mustBeFirstprivateBase(M, Kind);
849
0
  }
850
851
  /// Checks if the specified variable is a threadprivate.
852
0
  bool isThreadPrivate(VarDecl *D) {
853
0
    const DSAVarData DVar = getTopDSA(D, false);
854
0
    return isOpenMPThreadPrivate(DVar.CKind);
855
0
  }
856
857
  /// Marks current region as ordered (it has an 'ordered' clause).
858
  void setOrderedRegion(bool IsOrdered, const Expr *Param,
859
0
                        OMPOrderedClause *Clause) {
860
0
    if (IsOrdered)
861
0
      getTopOfStack().OrderedRegion.emplace(Param, Clause);
862
0
    else
863
0
      getTopOfStack().OrderedRegion.reset();
864
0
  }
865
  /// Returns true, if region is ordered (has associated 'ordered' clause),
866
  /// false - otherwise.
867
0
  bool isOrderedRegion() const {
868
0
    if (const SharingMapTy *Top = getTopOfStackOrNull())
869
0
      return Top->OrderedRegion.has_value();
870
0
    return false;
871
0
  }
872
  /// Returns optional parameter for the ordered region.
873
0
  std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
874
0
    if (const SharingMapTy *Top = getTopOfStackOrNull())
875
0
      if (Top->OrderedRegion)
876
0
        return *Top->OrderedRegion;
877
0
    return std::make_pair(nullptr, nullptr);
878
0
  }
879
  /// Returns true, if parent region is ordered (has associated
880
  /// 'ordered' clause), false - otherwise.
881
0
  bool isParentOrderedRegion() const {
882
0
    if (const SharingMapTy *Parent = getSecondOnStackOrNull())
883
0
      return Parent->OrderedRegion.has_value();
884
0
    return false;
885
0
  }
886
  /// Returns optional parameter for the ordered region.
887
  std::pair<const Expr *, OMPOrderedClause *>
888
0
  getParentOrderedRegionParam() const {
889
0
    if (const SharingMapTy *Parent = getSecondOnStackOrNull())
890
0
      if (Parent->OrderedRegion)
891
0
        return *Parent->OrderedRegion;
892
0
    return std::make_pair(nullptr, nullptr);
893
0
  }
894
  /// Marks current region as having an 'order' clause.
895
0
  void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
896
0
    getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
897
0
  }
898
  /// Returns true, if parent region is order (has associated
899
  /// 'order' clause), false - otherwise.
900
0
  bool isParentOrderConcurrent() const {
901
0
    if (const SharingMapTy *Parent = getSecondOnStackOrNull())
902
0
      return Parent->RegionHasOrderConcurrent;
903
0
    return false;
904
0
  }
905
  /// Marks current region as nowait (it has a 'nowait' clause).
906
0
  void setNowaitRegion(bool IsNowait = true) {
907
0
    getTopOfStack().NowaitRegion = IsNowait;
908
0
  }
909
  /// Returns true, if parent region is nowait (has associated
910
  /// 'nowait' clause), false - otherwise.
911
0
  bool isParentNowaitRegion() const {
912
0
    if (const SharingMapTy *Parent = getSecondOnStackOrNull())
913
0
      return Parent->NowaitRegion;
914
0
    return false;
915
0
  }
916
  /// Marks current region as untied (it has a 'untied' clause).
917
0
  void setUntiedRegion(bool IsUntied = true) {
918
0
    getTopOfStack().UntiedRegion = IsUntied;
919
0
  }
920
  /// Return true if current region is untied.
921
0
  bool isUntiedRegion() const {
922
0
    const SharingMapTy *Top = getTopOfStackOrNull();
923
0
    return Top ? Top->UntiedRegion : false;
924
0
  }
925
  /// Marks parent region as cancel region.
926
0
  void setParentCancelRegion(bool Cancel = true) {
927
0
    if (SharingMapTy *Parent = getSecondOnStackOrNull())
928
0
      Parent->CancelRegion |= Cancel;
929
0
  }
930
  /// Return true if current region has inner cancel construct.
931
0
  bool isCancelRegion() const {
932
0
    const SharingMapTy *Top = getTopOfStackOrNull();
933
0
    return Top ? Top->CancelRegion : false;
934
0
  }
935
936
  /// Mark that parent region already has scan directive.
937
0
  void setParentHasScanDirective(SourceLocation Loc) {
938
0
    if (SharingMapTy *Parent = getSecondOnStackOrNull())
939
0
      Parent->PrevScanLocation = Loc;
940
0
  }
941
  /// Return true if current region has inner cancel construct.
942
0
  bool doesParentHasScanDirective() const {
943
0
    const SharingMapTy *Top = getSecondOnStackOrNull();
944
0
    return Top ? Top->PrevScanLocation.isValid() : false;
945
0
  }
946
  /// Return true if current region has inner cancel construct.
947
0
  SourceLocation getParentScanDirectiveLoc() const {
948
0
    const SharingMapTy *Top = getSecondOnStackOrNull();
949
0
    return Top ? Top->PrevScanLocation : SourceLocation();
950
0
  }
951
  /// Mark that parent region already has ordered directive.
952
0
  void setParentHasOrderedDirective(SourceLocation Loc) {
953
0
    if (SharingMapTy *Parent = getSecondOnStackOrNull())
954
0
      Parent->PrevOrderedLocation = Loc;
955
0
  }
956
  /// Return true if current region has inner ordered construct.
957
0
  bool doesParentHasOrderedDirective() const {
958
0
    const SharingMapTy *Top = getSecondOnStackOrNull();
959
0
    return Top ? Top->PrevOrderedLocation.isValid() : false;
960
0
  }
961
  /// Returns the location of the previously specified ordered directive.
962
0
  SourceLocation getParentOrderedDirectiveLoc() const {
963
0
    const SharingMapTy *Top = getSecondOnStackOrNull();
964
0
    return Top ? Top->PrevOrderedLocation : SourceLocation();
965
0
  }
966
967
  /// Set collapse value for the region.
968
0
  void setAssociatedLoops(unsigned Val) {
969
0
    getTopOfStack().AssociatedLoops = Val;
970
0
    if (Val > 1)
971
0
      getTopOfStack().HasMutipleLoops = true;
972
0
  }
973
  /// Return collapse value for region.
974
0
  unsigned getAssociatedLoops() const {
975
0
    const SharingMapTy *Top = getTopOfStackOrNull();
976
0
    return Top ? Top->AssociatedLoops : 0;
977
0
  }
978
  /// Returns true if the construct is associated with multiple loops.
979
0
  bool hasMutipleLoops() const {
980
0
    const SharingMapTy *Top = getTopOfStackOrNull();
981
0
    return Top ? Top->HasMutipleLoops : false;
982
0
  }
983
984
  /// Marks current target region as one with closely nested teams
985
  /// region.
986
0
  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
987
0
    if (SharingMapTy *Parent = getSecondOnStackOrNull())
988
0
      Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
989
0
  }
990
  /// Returns true, if current region has closely nested teams region.
991
0
  bool hasInnerTeamsRegion() const {
992
0
    return getInnerTeamsRegionLoc().isValid();
993
0
  }
994
  /// Returns location of the nested teams region (if any).
995
0
  SourceLocation getInnerTeamsRegionLoc() const {
996
0
    const SharingMapTy *Top = getTopOfStackOrNull();
997
0
    return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
998
0
  }
999
1000
0
  Scope *getCurScope() const {
1001
0
    const SharingMapTy *Top = getTopOfStackOrNull();
1002
0
    return Top ? Top->CurScope : nullptr;
1003
0
  }
1004
0
  void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
1005
0
  SourceLocation getConstructLoc() const {
1006
0
    const SharingMapTy *Top = getTopOfStackOrNull();
1007
0
    return Top ? Top->ConstructLoc : SourceLocation();
1008
0
  }
1009
1010
  /// Do the check specified in \a Check to all component lists and return true
1011
  /// if any issue is found.
1012
  bool checkMappableExprComponentListsForDecl(
1013
      const ValueDecl *VD, bool CurrentRegionOnly,
1014
      const llvm::function_ref<
1015
          bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1016
               OpenMPClauseKind)>
1017
0
          Check) const {
1018
0
    if (isStackEmpty())
1019
0
      return false;
1020
0
    auto SI = begin();
1021
0
    auto SE = end();
1022
1023
0
    if (SI == SE)
1024
0
      return false;
1025
1026
0
    if (CurrentRegionOnly)
1027
0
      SE = std::next(SI);
1028
0
    else
1029
0
      std::advance(SI, 1);
1030
1031
0
    for (; SI != SE; ++SI) {
1032
0
      auto MI = SI->MappedExprComponents.find(VD);
1033
0
      if (MI != SI->MappedExprComponents.end())
1034
0
        for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1035
0
             MI->second.Components)
1036
0
          if (Check(L, MI->second.Kind))
1037
0
            return true;
1038
0
    }
1039
0
    return false;
1040
0
  }
1041
1042
  /// Do the check specified in \a Check to all component lists at a given level
1043
  /// and return true if any issue is found.
1044
  bool checkMappableExprComponentListsForDeclAtLevel(
1045
      const ValueDecl *VD, unsigned Level,
1046
      const llvm::function_ref<
1047
          bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1048
               OpenMPClauseKind)>
1049
0
          Check) const {
1050
0
    if (getStackSize() <= Level)
1051
0
      return false;
1052
1053
0
    const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1054
0
    auto MI = StackElem.MappedExprComponents.find(VD);
1055
0
    if (MI != StackElem.MappedExprComponents.end())
1056
0
      for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1057
0
           MI->second.Components)
1058
0
        if (Check(L, MI->second.Kind))
1059
0
          return true;
1060
0
    return false;
1061
0
  }
1062
1063
  /// Create a new mappable expression component list associated with a given
1064
  /// declaration and initialize it with the provided list of components.
1065
  void addMappableExpressionComponents(
1066
      const ValueDecl *VD,
1067
      OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1068
0
      OpenMPClauseKind WhereFoundClauseKind) {
1069
0
    MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1070
    // Create new entry and append the new components there.
1071
0
    MEC.Components.resize(MEC.Components.size() + 1);
1072
0
    MEC.Components.back().append(Components.begin(), Components.end());
1073
0
    MEC.Kind = WhereFoundClauseKind;
1074
0
  }
1075
1076
0
  unsigned getNestingLevel() const {
1077
0
    assert(!isStackEmpty());
1078
0
    return getStackSize() - 1;
1079
0
  }
1080
0
  void addDoacrossDependClause(OMPClause *C, const OperatorOffsetTy &OpsOffs) {
1081
0
    SharingMapTy *Parent = getSecondOnStackOrNull();
1082
0
    assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1083
0
    Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1084
0
  }
1085
  llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
1086
0
  getDoacrossDependClauses() const {
1087
0
    const SharingMapTy &StackElem = getTopOfStack();
1088
0
    if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1089
0
      const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1090
0
      return llvm::make_range(Ref.begin(), Ref.end());
1091
0
    }
1092
0
    return llvm::make_range(StackElem.DoacrossDepends.end(),
1093
0
                            StackElem.DoacrossDepends.end());
1094
0
  }
1095
1096
  // Store types of classes which have been explicitly mapped
1097
0
  void addMappedClassesQualTypes(QualType QT) {
1098
0
    SharingMapTy &StackElem = getTopOfStack();
1099
0
    StackElem.MappedClassesQualTypes.insert(QT);
1100
0
  }
1101
1102
  // Return set of mapped classes types
1103
0
  bool isClassPreviouslyMapped(QualType QT) const {
1104
0
    const SharingMapTy &StackElem = getTopOfStack();
1105
0
    return StackElem.MappedClassesQualTypes.contains(QT);
1106
0
  }
1107
1108
  /// Adds global declare target to the parent target region.
1109
0
  void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1110
0
    assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1111
0
               E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1112
0
           "Expected declare target link global.");
1113
0
    for (auto &Elem : *this) {
1114
0
      if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1115
0
        Elem.DeclareTargetLinkVarDecls.push_back(E);
1116
0
        return;
1117
0
      }
1118
0
    }
1119
0
  }
1120
1121
  /// Returns the list of globals with declare target link if current directive
1122
  /// is target.
1123
0
  ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1124
0
    assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1125
0
           "Expected target executable directive.");
1126
0
    return getTopOfStack().DeclareTargetLinkVarDecls;
1127
0
  }
1128
1129
  /// Adds list of allocators expressions.
1130
0
  void addInnerAllocatorExpr(Expr *E) {
1131
0
    getTopOfStack().InnerUsedAllocators.push_back(E);
1132
0
  }
1133
  /// Return list of used allocators.
1134
0
  ArrayRef<Expr *> getInnerAllocators() const {
1135
0
    return getTopOfStack().InnerUsedAllocators;
1136
0
  }
1137
  /// Marks the declaration as implicitly firstprivate nin the task-based
1138
  /// regions.
1139
0
  void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1140
0
    getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1141
0
  }
1142
  /// Checks if the decl is implicitly firstprivate in the task-based region.
1143
0
  bool isImplicitTaskFirstprivate(Decl *D) const {
1144
0
    return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1145
0
  }
1146
1147
  /// Marks decl as used in uses_allocators clause as the allocator.
1148
0
  void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1149
0
    getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1150
0
  }
1151
  /// Checks if specified decl is used in uses allocator clause as the
1152
  /// allocator.
1153
  std::optional<UsesAllocatorsDeclKind>
1154
0
  isUsesAllocatorsDecl(unsigned Level, const Decl *D) const {
1155
0
    const SharingMapTy &StackElem = getTopOfStack();
1156
0
    auto I = StackElem.UsesAllocatorsDecls.find(D);
1157
0
    if (I == StackElem.UsesAllocatorsDecls.end())
1158
0
      return std::nullopt;
1159
0
    return I->getSecond();
1160
0
  }
1161
  std::optional<UsesAllocatorsDeclKind>
1162
0
  isUsesAllocatorsDecl(const Decl *D) const {
1163
0
    const SharingMapTy &StackElem = getTopOfStack();
1164
0
    auto I = StackElem.UsesAllocatorsDecls.find(D);
1165
0
    if (I == StackElem.UsesAllocatorsDecls.end())
1166
0
      return std::nullopt;
1167
0
    return I->getSecond();
1168
0
  }
1169
1170
0
  void addDeclareMapperVarRef(Expr *Ref) {
1171
0
    SharingMapTy &StackElem = getTopOfStack();
1172
0
    StackElem.DeclareMapperVar = Ref;
1173
0
  }
1174
0
  const Expr *getDeclareMapperVarRef() const {
1175
0
    const SharingMapTy *Top = getTopOfStackOrNull();
1176
0
    return Top ? Top->DeclareMapperVar : nullptr;
1177
0
  }
1178
1179
  /// Add a new iterator variable.
1180
0
  void addIteratorVarDecl(VarDecl *VD) {
1181
0
    SharingMapTy &StackElem = getTopOfStack();
1182
0
    StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl());
1183
0
  }
1184
  /// Check if variable declaration is an iterator VarDecl.
1185
0
  bool isIteratorVarDecl(const VarDecl *VD) const {
1186
0
    const SharingMapTy *Top = getTopOfStackOrNull();
1187
0
    if (!Top)
1188
0
      return false;
1189
1190
0
    return llvm::is_contained(Top->IteratorVarDecls, VD->getCanonicalDecl());
1191
0
  }
1192
  /// get captured field from ImplicitDefaultFirstprivateFDs
1193
0
  VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
1194
0
    const_iterator I = begin();
1195
0
    const_iterator EndI = end();
1196
0
    size_t StackLevel = getStackSize();
1197
0
    for (; I != EndI; ++I) {
1198
0
      if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1199
0
        break;
1200
0
      StackLevel--;
1201
0
    }
1202
0
    assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1203
0
    if (I == EndI)
1204
0
      return nullptr;
1205
0
    for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1206
0
      if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1207
0
        return IFD.VD;
1208
0
    return nullptr;
1209
0
  }
1210
  /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
1211
0
  bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
1212
0
    const_iterator I = begin();
1213
0
    const_iterator EndI = end();
1214
0
    for (; I != EndI; ++I)
1215
0
      if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1216
0
        break;
1217
0
    if (I == EndI)
1218
0
      return false;
1219
0
    for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1220
0
      if (IFD.VD == VD)
1221
0
        return true;
1222
0
    return false;
1223
0
  }
1224
  /// Store capture FD info in ImplicitDefaultFirstprivateFDs
1225
0
  void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
1226
0
    iterator I = begin();
1227
0
    const_iterator EndI = end();
1228
0
    size_t StackLevel = getStackSize();
1229
0
    for (; I != EndI; ++I) {
1230
0
      if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1231
0
        I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1232
0
        break;
1233
0
      }
1234
0
      StackLevel--;
1235
0
    }
1236
0
    assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1237
0
  }
1238
};
1239
1240
0
bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1241
0
  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1242
0
}
1243
1244
0
bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1245
0
  return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1246
0
         DKind == OMPD_unknown;
1247
0
}
1248
1249
} // namespace
1250
1251
0
static const Expr *getExprAsWritten(const Expr *E) {
1252
0
  if (const auto *FE = dyn_cast<FullExpr>(E))
1253
0
    E = FE->getSubExpr();
1254
1255
0
  if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1256
0
    E = MTE->getSubExpr();
1257
1258
0
  while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1259
0
    E = Binder->getSubExpr();
1260
1261
0
  if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1262
0
    E = ICE->getSubExprAsWritten();
1263
0
  return E->IgnoreParens();
1264
0
}
1265
1266
0
static Expr *getExprAsWritten(Expr *E) {
1267
0
  return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1268
0
}
1269
1270
0
static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1271
0
  if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1272
0
    if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1273
0
      D = ME->getMemberDecl();
1274
0
  const auto *VD = dyn_cast<VarDecl>(D);
1275
0
  const auto *FD = dyn_cast<FieldDecl>(D);
1276
0
  if (VD != nullptr) {
1277
0
    VD = VD->getCanonicalDecl();
1278
0
    D = VD;
1279
0
  } else {
1280
0
    assert(FD);
1281
0
    FD = FD->getCanonicalDecl();
1282
0
    D = FD;
1283
0
  }
1284
0
  return D;
1285
0
}
1286
1287
0
static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1288
0
  return const_cast<ValueDecl *>(
1289
0
      getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1290
0
}
1291
1292
DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1293
0
                                          ValueDecl *D) const {
1294
0
  D = getCanonicalDecl(D);
1295
0
  auto *VD = dyn_cast<VarDecl>(D);
1296
0
  const auto *FD = dyn_cast<FieldDecl>(D);
1297
0
  DSAVarData DVar;
1298
0
  if (Iter == end()) {
1299
    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1300
    // in a region but not in construct]
1301
    //  File-scope or namespace-scope variables referenced in called routines
1302
    //  in the region are shared unless they appear in a threadprivate
1303
    //  directive.
1304
0
    if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1305
0
      DVar.CKind = OMPC_shared;
1306
1307
    // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1308
    // in a region but not in construct]
1309
    //  Variables with static storage duration that are declared in called
1310
    //  routines in the region are shared.
1311
0
    if (VD && VD->hasGlobalStorage())
1312
0
      DVar.CKind = OMPC_shared;
1313
1314
    // Non-static data members are shared by default.
1315
0
    if (FD)
1316
0
      DVar.CKind = OMPC_shared;
1317
1318
0
    return DVar;
1319
0
  }
1320
1321
  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1322
  // in a Construct, C/C++, predetermined, p.1]
1323
  // Variables with automatic storage duration that are declared in a scope
1324
  // inside the construct are private.
1325
0
  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1326
0
      (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1327
0
    DVar.CKind = OMPC_private;
1328
0
    return DVar;
1329
0
  }
1330
1331
0
  DVar.DKind = Iter->Directive;
1332
  // Explicitly specified attributes and local variables with predetermined
1333
  // attributes.
1334
0
  if (Iter->SharingMap.count(D)) {
1335
0
    const DSAInfo &Data = Iter->SharingMap.lookup(D);
1336
0
    DVar.RefExpr = Data.RefExpr.getPointer();
1337
0
    DVar.PrivateCopy = Data.PrivateCopy;
1338
0
    DVar.CKind = Data.Attributes;
1339
0
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1340
0
    DVar.Modifier = Data.Modifier;
1341
0
    DVar.AppliedToPointee = Data.AppliedToPointee;
1342
0
    return DVar;
1343
0
  }
1344
1345
  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1346
  // in a Construct, C/C++, implicitly determined, p.1]
1347
  //  In a parallel or task construct, the data-sharing attributes of these
1348
  //  variables are determined by the default clause, if present.
1349
0
  switch (Iter->DefaultAttr) {
1350
0
  case DSA_shared:
1351
0
    DVar.CKind = OMPC_shared;
1352
0
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1353
0
    return DVar;
1354
0
  case DSA_none:
1355
0
    return DVar;
1356
0
  case DSA_firstprivate:
1357
0
    if (VD && VD->getStorageDuration() == SD_Static &&
1358
0
        VD->getDeclContext()->isFileContext()) {
1359
0
      DVar.CKind = OMPC_unknown;
1360
0
    } else {
1361
0
      DVar.CKind = OMPC_firstprivate;
1362
0
    }
1363
0
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1364
0
    return DVar;
1365
0
  case DSA_private:
1366
    // each variable with static storage duration that is declared
1367
    // in a namespace or global scope and referenced in the construct,
1368
    // and that does not have a predetermined data-sharing attribute
1369
0
    if (VD && VD->getStorageDuration() == SD_Static &&
1370
0
        VD->getDeclContext()->isFileContext()) {
1371
0
      DVar.CKind = OMPC_unknown;
1372
0
    } else {
1373
0
      DVar.CKind = OMPC_private;
1374
0
    }
1375
0
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1376
0
    return DVar;
1377
0
  case DSA_unspecified:
1378
    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1379
    // in a Construct, implicitly determined, p.2]
1380
    //  In a parallel construct, if no default clause is present, these
1381
    //  variables are shared.
1382
0
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1383
0
    if ((isOpenMPParallelDirective(DVar.DKind) &&
1384
0
         !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1385
0
        isOpenMPTeamsDirective(DVar.DKind)) {
1386
0
      DVar.CKind = OMPC_shared;
1387
0
      return DVar;
1388
0
    }
1389
1390
    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1391
    // in a Construct, implicitly determined, p.4]
1392
    //  In a task construct, if no default clause is present, a variable that in
1393
    //  the enclosing context is determined to be shared by all implicit tasks
1394
    //  bound to the current team is shared.
1395
0
    if (isOpenMPTaskingDirective(DVar.DKind)) {
1396
0
      DSAVarData DVarTemp;
1397
0
      const_iterator I = Iter, E = end();
1398
0
      do {
1399
0
        ++I;
1400
        // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1401
        // Referenced in a Construct, implicitly determined, p.6]
1402
        //  In a task construct, if no default clause is present, a variable
1403
        //  whose data-sharing attribute is not determined by the rules above is
1404
        //  firstprivate.
1405
0
        DVarTemp = getDSA(I, D);
1406
0
        if (DVarTemp.CKind != OMPC_shared) {
1407
0
          DVar.RefExpr = nullptr;
1408
0
          DVar.CKind = OMPC_firstprivate;
1409
0
          return DVar;
1410
0
        }
1411
0
      } while (I != E && !isImplicitTaskingRegion(I->Directive));
1412
0
      DVar.CKind =
1413
0
          (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1414
0
      return DVar;
1415
0
    }
1416
0
  }
1417
  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1418
  // in a Construct, implicitly determined, p.3]
1419
  //  For constructs other than task, if no default clause is present, these
1420
  //  variables inherit their data-sharing attributes from the enclosing
1421
  //  context.
1422
0
  return getDSA(++Iter, D);
1423
0
}
1424
1425
const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1426
0
                                         const Expr *NewDE) {
1427
0
  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1428
0
  D = getCanonicalDecl(D);
1429
0
  SharingMapTy &StackElem = getTopOfStack();
1430
0
  auto It = StackElem.AlignedMap.find(D);
1431
0
  if (It == StackElem.AlignedMap.end()) {
1432
0
    assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1433
0
    StackElem.AlignedMap[D] = NewDE;
1434
0
    return nullptr;
1435
0
  }
1436
0
  assert(It->second && "Unexpected nullptr expr in the aligned map");
1437
0
  return It->second;
1438
0
}
1439
1440
const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1441
0
                                             const Expr *NewDE) {
1442
0
  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1443
0
  D = getCanonicalDecl(D);
1444
0
  SharingMapTy &StackElem = getTopOfStack();
1445
0
  auto It = StackElem.NontemporalMap.find(D);
1446
0
  if (It == StackElem.NontemporalMap.end()) {
1447
0
    assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1448
0
    StackElem.NontemporalMap[D] = NewDE;
1449
0
    return nullptr;
1450
0
  }
1451
0
  assert(It->second && "Unexpected nullptr expr in the aligned map");
1452
0
  return It->second;
1453
0
}
1454
1455
0
void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1456
0
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1457
0
  D = getCanonicalDecl(D);
1458
0
  SharingMapTy &StackElem = getTopOfStack();
1459
0
  StackElem.LCVMap.try_emplace(
1460
0
      D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1461
0
}
1462
1463
const DSAStackTy::LCDeclInfo
1464
0
DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1465
0
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1466
0
  D = getCanonicalDecl(D);
1467
0
  const SharingMapTy &StackElem = getTopOfStack();
1468
0
  auto It = StackElem.LCVMap.find(D);
1469
0
  if (It != StackElem.LCVMap.end())
1470
0
    return It->second;
1471
0
  return {0, nullptr};
1472
0
}
1473
1474
const DSAStackTy::LCDeclInfo
1475
0
DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1476
0
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1477
0
  D = getCanonicalDecl(D);
1478
0
  for (unsigned I = Level + 1; I > 0; --I) {
1479
0
    const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1480
0
    auto It = StackElem.LCVMap.find(D);
1481
0
    if (It != StackElem.LCVMap.end())
1482
0
      return It->second;
1483
0
  }
1484
0
  return {0, nullptr};
1485
0
}
1486
1487
const DSAStackTy::LCDeclInfo
1488
0
DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1489
0
  const SharingMapTy *Parent = getSecondOnStackOrNull();
1490
0
  assert(Parent && "Data-sharing attributes stack is empty");
1491
0
  D = getCanonicalDecl(D);
1492
0
  auto It = Parent->LCVMap.find(D);
1493
0
  if (It != Parent->LCVMap.end())
1494
0
    return It->second;
1495
0
  return {0, nullptr};
1496
0
}
1497
1498
0
const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1499
0
  const SharingMapTy *Parent = getSecondOnStackOrNull();
1500
0
  assert(Parent && "Data-sharing attributes stack is empty");
1501
0
  if (Parent->LCVMap.size() < I)
1502
0
    return nullptr;
1503
0
  for (const auto &Pair : Parent->LCVMap)
1504
0
    if (Pair.second.first == I)
1505
0
      return Pair.first;
1506
0
  return nullptr;
1507
0
}
1508
1509
void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1510
                        DeclRefExpr *PrivateCopy, unsigned Modifier,
1511
0
                        bool AppliedToPointee) {
1512
0
  D = getCanonicalDecl(D);
1513
0
  if (A == OMPC_threadprivate) {
1514
0
    DSAInfo &Data = Threadprivates[D];
1515
0
    Data.Attributes = A;
1516
0
    Data.RefExpr.setPointer(E);
1517
0
    Data.PrivateCopy = nullptr;
1518
0
    Data.Modifier = Modifier;
1519
0
  } else {
1520
0
    DSAInfo &Data = getTopOfStack().SharingMap[D];
1521
0
    assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1522
0
           (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1523
0
           (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1524
0
           (isLoopControlVariable(D).first && A == OMPC_private));
1525
0
    Data.Modifier = Modifier;
1526
0
    if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1527
0
      Data.RefExpr.setInt(/*IntVal=*/true);
1528
0
      return;
1529
0
    }
1530
0
    const bool IsLastprivate =
1531
0
        A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1532
0
    Data.Attributes = A;
1533
0
    Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1534
0
    Data.PrivateCopy = PrivateCopy;
1535
0
    Data.AppliedToPointee = AppliedToPointee;
1536
0
    if (PrivateCopy) {
1537
0
      DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1538
0
      Data.Modifier = Modifier;
1539
0
      Data.Attributes = A;
1540
0
      Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1541
0
      Data.PrivateCopy = nullptr;
1542
0
      Data.AppliedToPointee = AppliedToPointee;
1543
0
    }
1544
0
  }
1545
0
}
1546
1547
/// Build a variable declaration for OpenMP loop iteration variable.
1548
static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1549
                             StringRef Name, const AttrVec *Attrs = nullptr,
1550
0
                             DeclRefExpr *OrigRef = nullptr) {
1551
0
  DeclContext *DC = SemaRef.CurContext;
1552
0
  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1553
0
  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1554
0
  auto *Decl =
1555
0
      VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1556
0
  if (Attrs) {
1557
0
    for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1558
0
         I != E; ++I)
1559
0
      Decl->addAttr(*I);
1560
0
  }
1561
0
  Decl->setImplicit();
1562
0
  if (OrigRef) {
1563
0
    Decl->addAttr(
1564
0
        OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1565
0
  }
1566
0
  return Decl;
1567
0
}
1568
1569
static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1570
                                     SourceLocation Loc,
1571
0
                                     bool RefersToCapture = false) {
1572
0
  D->setReferenced();
1573
0
  D->markUsed(S.Context);
1574
0
  return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1575
0
                             SourceLocation(), D, RefersToCapture, Loc, Ty,
1576
0
                             VK_LValue);
1577
0
}
1578
1579
void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1580
0
                                           BinaryOperatorKind BOK) {
1581
0
  D = getCanonicalDecl(D);
1582
0
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1583
0
  assert(
1584
0
      getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1585
0
      "Additional reduction info may be specified only for reduction items.");
1586
0
  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1587
0
  assert(ReductionData.ReductionRange.isInvalid() &&
1588
0
         (getTopOfStack().Directive == OMPD_taskgroup ||
1589
0
          ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1590
0
            isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1591
0
           !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1592
0
         "Additional reduction info may be specified only once for reduction "
1593
0
         "items.");
1594
0
  ReductionData.set(BOK, SR);
1595
0
  Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1596
0
  if (!TaskgroupReductionRef) {
1597
0
    VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1598
0
                               SemaRef.Context.VoidPtrTy, ".task_red.");
1599
0
    TaskgroupReductionRef =
1600
0
        buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1601
0
  }
1602
0
}
1603
1604
void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1605
0
                                           const Expr *ReductionRef) {
1606
0
  D = getCanonicalDecl(D);
1607
0
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1608
0
  assert(
1609
0
      getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1610
0
      "Additional reduction info may be specified only for reduction items.");
1611
0
  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1612
0
  assert(ReductionData.ReductionRange.isInvalid() &&
1613
0
         (getTopOfStack().Directive == OMPD_taskgroup ||
1614
0
          ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1615
0
            isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1616
0
           !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1617
0
         "Additional reduction info may be specified only once for reduction "
1618
0
         "items.");
1619
0
  ReductionData.set(ReductionRef, SR);
1620
0
  Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1621
0
  if (!TaskgroupReductionRef) {
1622
0
    VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1623
0
                               SemaRef.Context.VoidPtrTy, ".task_red.");
1624
0
    TaskgroupReductionRef =
1625
0
        buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1626
0
  }
1627
0
}
1628
1629
const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1630
    const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1631
0
    Expr *&TaskgroupDescriptor) const {
1632
0
  D = getCanonicalDecl(D);
1633
0
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1634
0
  for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1635
0
    const DSAInfo &Data = I->SharingMap.lookup(D);
1636
0
    if (Data.Attributes != OMPC_reduction ||
1637
0
        Data.Modifier != OMPC_REDUCTION_task)
1638
0
      continue;
1639
0
    const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1640
0
    if (!ReductionData.ReductionOp ||
1641
0
        ReductionData.ReductionOp.is<const Expr *>())
1642
0
      return DSAVarData();
1643
0
    SR = ReductionData.ReductionRange;
1644
0
    BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1645
0
    assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1646
0
                                       "expression for the descriptor is not "
1647
0
                                       "set.");
1648
0
    TaskgroupDescriptor = I->TaskgroupReductionRef;
1649
0
    return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1650
0
                      Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1651
0
                      /*AppliedToPointee=*/false);
1652
0
  }
1653
0
  return DSAVarData();
1654
0
}
1655
1656
const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1657
    const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1658
0
    Expr *&TaskgroupDescriptor) const {
1659
0
  D = getCanonicalDecl(D);
1660
0
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1661
0
  for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1662
0
    const DSAInfo &Data = I->SharingMap.lookup(D);
1663
0
    if (Data.Attributes != OMPC_reduction ||
1664
0
        Data.Modifier != OMPC_REDUCTION_task)
1665
0
      continue;
1666
0
    const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1667
0
    if (!ReductionData.ReductionOp ||
1668
0
        !ReductionData.ReductionOp.is<const Expr *>())
1669
0
      return DSAVarData();
1670
0
    SR = ReductionData.ReductionRange;
1671
0
    ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1672
0
    assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1673
0
                                       "expression for the descriptor is not "
1674
0
                                       "set.");
1675
0
    TaskgroupDescriptor = I->TaskgroupReductionRef;
1676
0
    return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1677
0
                      Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1678
0
                      /*AppliedToPointee=*/false);
1679
0
  }
1680
0
  return DSAVarData();
1681
0
}
1682
1683
0
bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1684
0
  D = D->getCanonicalDecl();
1685
0
  for (const_iterator E = end(); I != E; ++I) {
1686
0
    if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1687
0
        isOpenMPTargetExecutionDirective(I->Directive)) {
1688
0
      if (I->CurScope) {
1689
0
        Scope *TopScope = I->CurScope->getParent();
1690
0
        Scope *CurScope = getCurScope();
1691
0
        while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1692
0
          CurScope = CurScope->getParent();
1693
0
        return CurScope != TopScope;
1694
0
      }
1695
0
      for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1696
0
        if (I->Context == DC)
1697
0
          return true;
1698
0
      return false;
1699
0
    }
1700
0
  }
1701
0
  return false;
1702
0
}
1703
1704
static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1705
                                  bool AcceptIfMutable = true,
1706
0
                                  bool *IsClassType = nullptr) {
1707
0
  ASTContext &Context = SemaRef.getASTContext();
1708
0
  Type = Type.getNonReferenceType().getCanonicalType();
1709
0
  bool IsConstant = Type.isConstant(Context);
1710
0
  Type = Context.getBaseElementType(Type);
1711
0
  const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1712
0
                                ? Type->getAsCXXRecordDecl()
1713
0
                                : nullptr;
1714
0
  if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1715
0
    if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1716
0
      RD = CTD->getTemplatedDecl();
1717
0
  if (IsClassType)
1718
0
    *IsClassType = RD;
1719
0
  return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1720
0
                         RD->hasDefinition() && RD->hasMutableFields());
1721
0
}
1722
1723
static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1724
                                      QualType Type, OpenMPClauseKind CKind,
1725
                                      SourceLocation ELoc,
1726
                                      bool AcceptIfMutable = true,
1727
0
                                      bool ListItemNotVar = false) {
1728
0
  ASTContext &Context = SemaRef.getASTContext();
1729
0
  bool IsClassType;
1730
0
  if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1731
0
    unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1732
0
                    : IsClassType  ? diag::err_omp_const_not_mutable_variable
1733
0
                                   : diag::err_omp_const_variable;
1734
0
    SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1735
0
    if (!ListItemNotVar && D) {
1736
0
      const VarDecl *VD = dyn_cast<VarDecl>(D);
1737
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1738
0
                               VarDecl::DeclarationOnly;
1739
0
      SemaRef.Diag(D->getLocation(),
1740
0
                   IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1741
0
          << D;
1742
0
    }
1743
0
    return true;
1744
0
  }
1745
0
  return false;
1746
0
}
1747
1748
const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1749
0
                                                   bool FromParent) {
1750
0
  D = getCanonicalDecl(D);
1751
0
  DSAVarData DVar;
1752
1753
0
  auto *VD = dyn_cast<VarDecl>(D);
1754
0
  auto TI = Threadprivates.find(D);
1755
0
  if (TI != Threadprivates.end()) {
1756
0
    DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1757
0
    DVar.CKind = OMPC_threadprivate;
1758
0
    DVar.Modifier = TI->getSecond().Modifier;
1759
0
    return DVar;
1760
0
  }
1761
0
  if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1762
0
    DVar.RefExpr = buildDeclRefExpr(
1763
0
        SemaRef, VD, D->getType().getNonReferenceType(),
1764
0
        VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1765
0
    DVar.CKind = OMPC_threadprivate;
1766
0
    addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1767
0
    return DVar;
1768
0
  }
1769
  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1770
  // in a Construct, C/C++, predetermined, p.1]
1771
  //  Variables appearing in threadprivate directives are threadprivate.
1772
0
  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1773
0
       !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1774
0
         SemaRef.getLangOpts().OpenMPUseTLS &&
1775
0
         SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1776
0
      (VD && VD->getStorageClass() == SC_Register &&
1777
0
       VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1778
0
    DVar.RefExpr = buildDeclRefExpr(
1779
0
        SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1780
0
    DVar.CKind = OMPC_threadprivate;
1781
0
    addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1782
0
    return DVar;
1783
0
  }
1784
0
  if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1785
0
      VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1786
0
      !isLoopControlVariable(D).first) {
1787
0
    const_iterator IterTarget =
1788
0
        std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1789
0
          return isOpenMPTargetExecutionDirective(Data.Directive);
1790
0
        });
1791
0
    if (IterTarget != end()) {
1792
0
      const_iterator ParentIterTarget = IterTarget + 1;
1793
0
      for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1794
0
        if (isOpenMPLocal(VD, Iter)) {
1795
0
          DVar.RefExpr =
1796
0
              buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1797
0
                               D->getLocation());
1798
0
          DVar.CKind = OMPC_threadprivate;
1799
0
          return DVar;
1800
0
        }
1801
0
      }
1802
0
      if (!isClauseParsingMode() || IterTarget != begin()) {
1803
0
        auto DSAIter = IterTarget->SharingMap.find(D);
1804
0
        if (DSAIter != IterTarget->SharingMap.end() &&
1805
0
            isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1806
0
          DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1807
0
          DVar.CKind = OMPC_threadprivate;
1808
0
          return DVar;
1809
0
        }
1810
0
        const_iterator End = end();
1811
0
        if (!SemaRef.isOpenMPCapturedByRef(D,
1812
0
                                           std::distance(ParentIterTarget, End),
1813
0
                                           /*OpenMPCaptureLevel=*/0)) {
1814
0
          DVar.RefExpr =
1815
0
              buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1816
0
                               IterTarget->ConstructLoc);
1817
0
          DVar.CKind = OMPC_threadprivate;
1818
0
          return DVar;
1819
0
        }
1820
0
      }
1821
0
    }
1822
0
  }
1823
1824
0
  if (isStackEmpty())
1825
    // Not in OpenMP execution region and top scope was already checked.
1826
0
    return DVar;
1827
1828
  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1829
  // in a Construct, C/C++, predetermined, p.4]
1830
  //  Static data members are shared.
1831
  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1832
  // in a Construct, C/C++, predetermined, p.7]
1833
  //  Variables with static storage duration that are declared in a scope
1834
  //  inside the construct are shared.
1835
0
  if (VD && VD->isStaticDataMember()) {
1836
    // Check for explicitly specified attributes.
1837
0
    const_iterator I = begin();
1838
0
    const_iterator EndI = end();
1839
0
    if (FromParent && I != EndI)
1840
0
      ++I;
1841
0
    if (I != EndI) {
1842
0
      auto It = I->SharingMap.find(D);
1843
0
      if (It != I->SharingMap.end()) {
1844
0
        const DSAInfo &Data = It->getSecond();
1845
0
        DVar.RefExpr = Data.RefExpr.getPointer();
1846
0
        DVar.PrivateCopy = Data.PrivateCopy;
1847
0
        DVar.CKind = Data.Attributes;
1848
0
        DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1849
0
        DVar.DKind = I->Directive;
1850
0
        DVar.Modifier = Data.Modifier;
1851
0
        DVar.AppliedToPointee = Data.AppliedToPointee;
1852
0
        return DVar;
1853
0
      }
1854
0
    }
1855
1856
0
    DVar.CKind = OMPC_shared;
1857
0
    return DVar;
1858
0
  }
1859
1860
0
  auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1861
  // The predetermined shared attribute for const-qualified types having no
1862
  // mutable members was removed after OpenMP 3.1.
1863
0
  if (SemaRef.LangOpts.OpenMP <= 31) {
1864
    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1865
    // in a Construct, C/C++, predetermined, p.6]
1866
    //  Variables with const qualified type having no mutable member are
1867
    //  shared.
1868
0
    if (isConstNotMutableType(SemaRef, D->getType())) {
1869
      // Variables with const-qualified type having no mutable member may be
1870
      // listed in a firstprivate clause, even if they are static data members.
1871
0
      DSAVarData DVarTemp = hasInnermostDSA(
1872
0
          D,
1873
0
          [](OpenMPClauseKind C, bool) {
1874
0
            return C == OMPC_firstprivate || C == OMPC_shared;
1875
0
          },
1876
0
          MatchesAlways, FromParent);
1877
0
      if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1878
0
        return DVarTemp;
1879
1880
0
      DVar.CKind = OMPC_shared;
1881
0
      return DVar;
1882
0
    }
1883
0
  }
1884
1885
  // Explicitly specified attributes and local variables with predetermined
1886
  // attributes.
1887
0
  const_iterator I = begin();
1888
0
  const_iterator EndI = end();
1889
0
  if (FromParent && I != EndI)
1890
0
    ++I;
1891
0
  if (I == EndI)
1892
0
    return DVar;
1893
0
  auto It = I->SharingMap.find(D);
1894
0
  if (It != I->SharingMap.end()) {
1895
0
    const DSAInfo &Data = It->getSecond();
1896
0
    DVar.RefExpr = Data.RefExpr.getPointer();
1897
0
    DVar.PrivateCopy = Data.PrivateCopy;
1898
0
    DVar.CKind = Data.Attributes;
1899
0
    DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1900
0
    DVar.DKind = I->Directive;
1901
0
    DVar.Modifier = Data.Modifier;
1902
0
    DVar.AppliedToPointee = Data.AppliedToPointee;
1903
0
  }
1904
1905
0
  return DVar;
1906
0
}
1907
1908
const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1909
0
                                                        bool FromParent) const {
1910
0
  if (isStackEmpty()) {
1911
0
    const_iterator I;
1912
0
    return getDSA(I, D);
1913
0
  }
1914
0
  D = getCanonicalDecl(D);
1915
0
  const_iterator StartI = begin();
1916
0
  const_iterator EndI = end();
1917
0
  if (FromParent && StartI != EndI)
1918
0
    ++StartI;
1919
0
  return getDSA(StartI, D);
1920
0
}
1921
1922
const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1923
0
                                                        unsigned Level) const {
1924
0
  if (getStackSize() <= Level)
1925
0
    return DSAVarData();
1926
0
  D = getCanonicalDecl(D);
1927
0
  const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1928
0
  return getDSA(StartI, D);
1929
0
}
1930
1931
const DSAStackTy::DSAVarData
1932
DSAStackTy::hasDSA(ValueDecl *D,
1933
                   const llvm::function_ref<bool(OpenMPClauseKind, bool,
1934
                                                 DefaultDataSharingAttributes)>
1935
                       CPred,
1936
                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1937
0
                   bool FromParent) const {
1938
0
  if (isStackEmpty())
1939
0
    return {};
1940
0
  D = getCanonicalDecl(D);
1941
0
  const_iterator I = begin();
1942
0
  const_iterator EndI = end();
1943
0
  if (FromParent && I != EndI)
1944
0
    ++I;
1945
0
  for (; I != EndI; ++I) {
1946
0
    if (!DPred(I->Directive) &&
1947
0
        !isImplicitOrExplicitTaskingRegion(I->Directive))
1948
0
      continue;
1949
0
    const_iterator NewI = I;
1950
0
    DSAVarData DVar = getDSA(NewI, D);
1951
0
    if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1952
0
      return DVar;
1953
0
  }
1954
0
  return {};
1955
0
}
1956
1957
const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1958
    ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1959
    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1960
0
    bool FromParent) const {
1961
0
  if (isStackEmpty())
1962
0
    return {};
1963
0
  D = getCanonicalDecl(D);
1964
0
  const_iterator StartI = begin();
1965
0
  const_iterator EndI = end();
1966
0
  if (FromParent && StartI != EndI)
1967
0
    ++StartI;
1968
0
  if (StartI == EndI || !DPred(StartI->Directive))
1969
0
    return {};
1970
0
  const_iterator NewI = StartI;
1971
0
  DSAVarData DVar = getDSA(NewI, D);
1972
0
  return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1973
0
             ? DVar
1974
0
             : DSAVarData();
1975
0
}
1976
1977
bool DSAStackTy::hasExplicitDSA(
1978
    const ValueDecl *D,
1979
    const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1980
0
    unsigned Level, bool NotLastprivate) const {
1981
0
  if (getStackSize() <= Level)
1982
0
    return false;
1983
0
  D = getCanonicalDecl(D);
1984
0
  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1985
0
  auto I = StackElem.SharingMap.find(D);
1986
0
  if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1987
0
      CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1988
0
      (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1989
0
    return true;
1990
  // Check predetermined rules for the loop control variables.
1991
0
  auto LI = StackElem.LCVMap.find(D);
1992
0
  if (LI != StackElem.LCVMap.end())
1993
0
    return CPred(OMPC_private, /*AppliedToPointee=*/false);
1994
0
  return false;
1995
0
}
1996
1997
bool DSAStackTy::hasExplicitDirective(
1998
    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1999
0
    unsigned Level) const {
2000
0
  if (getStackSize() <= Level)
2001
0
    return false;
2002
0
  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
2003
0
  return DPred(StackElem.Directive);
2004
0
}
2005
2006
bool DSAStackTy::hasDirective(
2007
    const llvm::function_ref<bool(OpenMPDirectiveKind,
2008
                                  const DeclarationNameInfo &, SourceLocation)>
2009
        DPred,
2010
0
    bool FromParent) const {
2011
  // We look only in the enclosing region.
2012
0
  size_t Skip = FromParent ? 2 : 1;
2013
0
  for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
2014
0
       I != E; ++I) {
2015
0
    if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
2016
0
      return true;
2017
0
  }
2018
0
  return false;
2019
0
}
2020
2021
46
void Sema::InitDataSharingAttributesStack() {
2022
46
  VarDataSharingAttributesStack = new DSAStackTy(*this);
2023
46
}
2024
2025
46
#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2026
2027
0
void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
2028
2029
0
void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
2030
0
  DSAStack->popFunction(OldFSI);
2031
0
}
2032
2033
0
static bool isOpenMPDeviceDelayedContext(Sema &S) {
2034
0
  assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsTargetDevice &&
2035
0
         "Expected OpenMP device compilation.");
2036
0
  return !S.isInOpenMPTargetExecutionDirective();
2037
0
}
2038
2039
namespace {
2040
/// Status of the function emission on the host/device.
2041
enum class FunctionEmissionStatus {
2042
  Emitted,
2043
  Discarded,
2044
  Unknown,
2045
};
2046
} // anonymous namespace
2047
2048
Sema::SemaDiagnosticBuilder
2049
Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID,
2050
0
                             const FunctionDecl *FD) {
2051
0
  assert(LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice &&
2052
0
         "Expected OpenMP device compilation.");
2053
2054
0
  SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2055
0
  if (FD) {
2056
0
    FunctionEmissionStatus FES = getEmissionStatus(FD);
2057
0
    switch (FES) {
2058
0
    case FunctionEmissionStatus::Emitted:
2059
0
      Kind = SemaDiagnosticBuilder::K_Immediate;
2060
0
      break;
2061
0
    case FunctionEmissionStatus::Unknown:
2062
      // TODO: We should always delay diagnostics here in case a target
2063
      //       region is in a function we do not emit. However, as the
2064
      //       current diagnostics are associated with the function containing
2065
      //       the target region and we do not emit that one, we would miss out
2066
      //       on diagnostics for the target region itself. We need to anchor
2067
      //       the diagnostics with the new generated function *or* ensure we
2068
      //       emit diagnostics associated with the surrounding function.
2069
0
      Kind = isOpenMPDeviceDelayedContext(*this)
2070
0
                 ? SemaDiagnosticBuilder::K_Deferred
2071
0
                 : SemaDiagnosticBuilder::K_Immediate;
2072
0
      break;
2073
0
    case FunctionEmissionStatus::TemplateDiscarded:
2074
0
    case FunctionEmissionStatus::OMPDiscarded:
2075
0
      Kind = SemaDiagnosticBuilder::K_Nop;
2076
0
      break;
2077
0
    case FunctionEmissionStatus::CUDADiscarded:
2078
0
      llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
2079
0
      break;
2080
0
    }
2081
0
  }
2082
2083
0
  return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2084
0
}
2085
2086
Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
2087
                                                       unsigned DiagID,
2088
0
                                                       const FunctionDecl *FD) {
2089
0
  assert(LangOpts.OpenMP && !LangOpts.OpenMPIsTargetDevice &&
2090
0
         "Expected OpenMP host compilation.");
2091
2092
0
  SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2093
0
  if (FD) {
2094
0
    FunctionEmissionStatus FES = getEmissionStatus(FD);
2095
0
    switch (FES) {
2096
0
    case FunctionEmissionStatus::Emitted:
2097
0
      Kind = SemaDiagnosticBuilder::K_Immediate;
2098
0
      break;
2099
0
    case FunctionEmissionStatus::Unknown:
2100
0
      Kind = SemaDiagnosticBuilder::K_Deferred;
2101
0
      break;
2102
0
    case FunctionEmissionStatus::TemplateDiscarded:
2103
0
    case FunctionEmissionStatus::OMPDiscarded:
2104
0
    case FunctionEmissionStatus::CUDADiscarded:
2105
0
      Kind = SemaDiagnosticBuilder::K_Nop;
2106
0
      break;
2107
0
    }
2108
0
  }
2109
2110
0
  return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2111
0
}
2112
2113
static OpenMPDefaultmapClauseKind
2114
0
getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
2115
0
  if (LO.OpenMP <= 45) {
2116
0
    if (VD->getType().getNonReferenceType()->isScalarType())
2117
0
      return OMPC_DEFAULTMAP_scalar;
2118
0
    return OMPC_DEFAULTMAP_aggregate;
2119
0
  }
2120
0
  if (VD->getType().getNonReferenceType()->isAnyPointerType())
2121
0
    return OMPC_DEFAULTMAP_pointer;
2122
0
  if (VD->getType().getNonReferenceType()->isScalarType())
2123
0
    return OMPC_DEFAULTMAP_scalar;
2124
0
  return OMPC_DEFAULTMAP_aggregate;
2125
0
}
2126
2127
bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
2128
0
                                 unsigned OpenMPCaptureLevel) const {
2129
0
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2130
2131
0
  ASTContext &Ctx = getASTContext();
2132
0
  bool IsByRef = true;
2133
2134
  // Find the directive that is associated with the provided scope.
2135
0
  D = cast<ValueDecl>(D->getCanonicalDecl());
2136
0
  QualType Ty = D->getType();
2137
2138
0
  bool IsVariableUsedInMapClause = false;
2139
0
  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2140
    // This table summarizes how a given variable should be passed to the device
2141
    // given its type and the clauses where it appears. This table is based on
2142
    // the description in OpenMP 4.5 [2.10.4, target Construct] and
2143
    // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2144
    //
2145
    // =========================================================================
2146
    // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
2147
    // |      |(tofrom:scalar)|     |  pvt  |               |has_dv_adr|       |
2148
    // =========================================================================
2149
    // | scl  |               |     |       |       -       |          | bycopy|
2150
    // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
2151
    // | scl  |               |  x  |   -   |       -       |     -    | null  |
2152
    // | scl  |       x       |     |       |       -       |          | byref |
2153
    // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
2154
    // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
2155
    // | scl  |               |  -  |   -   |       -       |     x    | byref |
2156
    // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
2157
    //
2158
    // | agg  |      n.a.     |     |       |       -       |          | byref |
2159
    // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2160
    // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2161
    // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2162
    // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2163
    //
2164
    // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2165
    // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2166
    // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2167
    // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2168
    // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2169
    // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2170
    // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2171
    // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2172
    // =========================================================================
2173
    // Legend:
2174
    //  scl - scalar
2175
    //  ptr - pointer
2176
    //  agg - aggregate
2177
    //  x - applies
2178
    //  - - invalid in this combination
2179
    //  [] - mapped with an array section
2180
    //  byref - should be mapped by reference
2181
    //  byval - should be mapped by value
2182
    //  null - initialize a local variable to null on the device
2183
    //
2184
    // Observations:
2185
    //  - All scalar declarations that show up in a map clause have to be passed
2186
    //    by reference, because they may have been mapped in the enclosing data
2187
    //    environment.
2188
    //  - If the scalar value does not fit the size of uintptr, it has to be
2189
    //    passed by reference, regardless the result in the table above.
2190
    //  - For pointers mapped by value that have either an implicit map or an
2191
    //    array section, the runtime library may pass the NULL value to the
2192
    //    device instead of the value passed to it by the compiler.
2193
2194
0
    if (Ty->isReferenceType())
2195
0
      Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2196
2197
    // Locate map clauses and see if the variable being captured is referred to
2198
    // in any of those clauses. Here we only care about variables, not fields,
2199
    // because fields are part of aggregates.
2200
0
    bool IsVariableAssociatedWithSection = false;
2201
2202
0
    DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2203
0
        D, Level,
2204
0
        [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2205
0
         D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2206
0
                MapExprComponents,
2207
0
            OpenMPClauseKind WhereFoundClauseKind) {
2208
          // Both map and has_device_addr clauses information influences how a
2209
          // variable is captured. E.g. is_device_ptr does not require changing
2210
          // the default behavior.
2211
0
          if (WhereFoundClauseKind != OMPC_map &&
2212
0
              WhereFoundClauseKind != OMPC_has_device_addr)
2213
0
            return false;
2214
2215
0
          auto EI = MapExprComponents.rbegin();
2216
0
          auto EE = MapExprComponents.rend();
2217
2218
0
          assert(EI != EE && "Invalid map expression!");
2219
2220
0
          if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2221
0
            IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2222
2223
0
          ++EI;
2224
0
          if (EI == EE)
2225
0
            return false;
2226
0
          auto Last = std::prev(EE);
2227
0
          const auto *UO =
2228
0
              dyn_cast<UnaryOperator>(Last->getAssociatedExpression());
2229
0
          if ((UO && UO->getOpcode() == UO_Deref) ||
2230
0
              isa<ArraySubscriptExpr>(Last->getAssociatedExpression()) ||
2231
0
              isa<OMPArraySectionExpr>(Last->getAssociatedExpression()) ||
2232
0
              isa<MemberExpr>(EI->getAssociatedExpression()) ||
2233
0
              isa<OMPArrayShapingExpr>(Last->getAssociatedExpression())) {
2234
0
            IsVariableAssociatedWithSection = true;
2235
            // There is nothing more we need to know about this variable.
2236
0
            return true;
2237
0
          }
2238
2239
          // Keep looking for more map info.
2240
0
          return false;
2241
0
        });
2242
2243
0
    if (IsVariableUsedInMapClause) {
2244
      // If variable is identified in a map clause it is always captured by
2245
      // reference except if it is a pointer that is dereferenced somehow.
2246
0
      IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2247
0
    } else {
2248
      // By default, all the data that has a scalar type is mapped by copy
2249
      // (except for reduction variables).
2250
      // Defaultmap scalar is mutual exclusive to defaultmap pointer
2251
0
      IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2252
0
                 !Ty->isAnyPointerType()) ||
2253
0
                !Ty->isScalarType() ||
2254
0
                DSAStack->isDefaultmapCapturedByRef(
2255
0
                    Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2256
0
                DSAStack->hasExplicitDSA(
2257
0
                    D,
2258
0
                    [](OpenMPClauseKind K, bool AppliedToPointee) {
2259
0
                      return K == OMPC_reduction && !AppliedToPointee;
2260
0
                    },
2261
0
                    Level);
2262
0
    }
2263
0
  }
2264
2265
0
  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2266
0
    IsByRef =
2267
0
        ((IsVariableUsedInMapClause &&
2268
0
          DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2269
0
              OMPD_target) ||
2270
0
         !(DSAStack->hasExplicitDSA(
2271
0
               D,
2272
0
               [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2273
0
                 return K == OMPC_firstprivate ||
2274
0
                        (K == OMPC_reduction && AppliedToPointee);
2275
0
               },
2276
0
               Level, /*NotLastprivate=*/true) ||
2277
0
           DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2278
        // If the variable is artificial and must be captured by value - try to
2279
        // capture by value.
2280
0
        !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2281
0
          !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2282
        // If the variable is implicitly firstprivate and scalar - capture by
2283
        // copy
2284
0
        !((DSAStack->getDefaultDSA() == DSA_firstprivate ||
2285
0
           DSAStack->getDefaultDSA() == DSA_private) &&
2286
0
          !DSAStack->hasExplicitDSA(
2287
0
              D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2288
0
              Level) &&
2289
0
          !DSAStack->isLoopControlVariable(D, Level).first);
2290
0
  }
2291
2292
  // When passing data by copy, we need to make sure it fits the uintptr size
2293
  // and alignment, because the runtime library only deals with uintptr types.
2294
  // If it does not fit the uintptr size, we need to pass the data by reference
2295
  // instead.
2296
0
  if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) >
2297
0
                       Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2298
0
                   Ctx.getAlignOfGlobalVarInChars(Ty) >
2299
0
                       Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2300
0
    IsByRef = true;
2301
0
  }
2302
2303
0
  return IsByRef;
2304
0
}
2305
2306
0
unsigned Sema::getOpenMPNestingLevel() const {
2307
0
  assert(getLangOpts().OpenMP);
2308
0
  return DSAStack->getNestingLevel();
2309
0
}
2310
2311
0
bool Sema::isInOpenMPTaskUntiedContext() const {
2312
0
  return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2313
0
         DSAStack->isUntiedRegion();
2314
0
}
2315
2316
0
bool Sema::isInOpenMPTargetExecutionDirective() const {
2317
0
  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2318
0
          !DSAStack->isClauseParsingMode()) ||
2319
0
         DSAStack->hasDirective(
2320
0
             [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2321
0
                SourceLocation) -> bool {
2322
0
               return isOpenMPTargetExecutionDirective(K);
2323
0
             },
2324
0
             false);
2325
0
}
2326
2327
0
bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
2328
  // Only rebuild for Field.
2329
0
  if (!dyn_cast<FieldDecl>(D))
2330
0
    return false;
2331
0
  DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2332
0
      D,
2333
0
      [](OpenMPClauseKind C, bool AppliedToPointee,
2334
0
         DefaultDataSharingAttributes DefaultAttr) {
2335
0
        return isOpenMPPrivate(C) && !AppliedToPointee &&
2336
0
               (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2337
0
      },
2338
0
      [](OpenMPDirectiveKind) { return true; },
2339
0
      DSAStack->isClauseParsingMode());
2340
0
  if (DVarPrivate.CKind != OMPC_unknown)
2341
0
    return true;
2342
0
  return false;
2343
0
}
2344
2345
static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2346
                                             Expr *CaptureExpr, bool WithInit,
2347
                                             DeclContext *CurContext,
2348
                                             bool AsExpression);
2349
2350
VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2351
0
                                    unsigned StopAt) {
2352
0
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2353
0
  D = getCanonicalDecl(D);
2354
2355
0
  auto *VD = dyn_cast<VarDecl>(D);
2356
  // Do not capture constexpr variables.
2357
0
  if (VD && VD->isConstexpr())
2358
0
    return nullptr;
2359
2360
  // If we want to determine whether the variable should be captured from the
2361
  // perspective of the current capturing scope, and we've already left all the
2362
  // capturing scopes of the top directive on the stack, check from the
2363
  // perspective of its parent directive (if any) instead.
2364
0
  DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2365
0
      *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2366
2367
  // If we are attempting to capture a global variable in a directive with
2368
  // 'target' we return true so that this global is also mapped to the device.
2369
  //
2370
0
  if (VD && !VD->hasLocalStorage() &&
2371
0
      (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2372
0
    if (isInOpenMPTargetExecutionDirective()) {
2373
0
      DSAStackTy::DSAVarData DVarTop =
2374
0
          DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2375
0
      if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2376
0
        return VD;
2377
      // If the declaration is enclosed in a 'declare target' directive,
2378
      // then it should not be captured.
2379
      //
2380
0
      if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2381
0
        return nullptr;
2382
0
      CapturedRegionScopeInfo *CSI = nullptr;
2383
0
      for (FunctionScopeInfo *FSI : llvm::drop_begin(
2384
0
               llvm::reverse(FunctionScopes),
2385
0
               CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2386
0
        if (!isa<CapturingScopeInfo>(FSI))
2387
0
          return nullptr;
2388
0
        if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2389
0
          if (RSI->CapRegionKind == CR_OpenMP) {
2390
0
            CSI = RSI;
2391
0
            break;
2392
0
          }
2393
0
      }
2394
0
      assert(CSI && "Failed to find CapturedRegionScopeInfo");
2395
0
      SmallVector<OpenMPDirectiveKind, 4> Regions;
2396
0
      getOpenMPCaptureRegions(Regions,
2397
0
                              DSAStack->getDirective(CSI->OpenMPLevel));
2398
0
      if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2399
0
        return VD;
2400
0
    }
2401
0
    if (isInOpenMPDeclareTargetContext()) {
2402
      // Try to mark variable as declare target if it is used in capturing
2403
      // regions.
2404
0
      if (LangOpts.OpenMP <= 45 &&
2405
0
          !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2406
0
        checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2407
0
      return nullptr;
2408
0
    }
2409
0
  }
2410
2411
0
  if (CheckScopeInfo) {
2412
0
    bool OpenMPFound = false;
2413
0
    for (unsigned I = StopAt + 1; I > 0; --I) {
2414
0
      FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2415
0
      if (!isa<CapturingScopeInfo>(FSI))
2416
0
        return nullptr;
2417
0
      if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2418
0
        if (RSI->CapRegionKind == CR_OpenMP) {
2419
0
          OpenMPFound = true;
2420
0
          break;
2421
0
        }
2422
0
    }
2423
0
    if (!OpenMPFound)
2424
0
      return nullptr;
2425
0
  }
2426
2427
0
  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2428
0
      (!DSAStack->isClauseParsingMode() ||
2429
0
       DSAStack->getParentDirective() != OMPD_unknown)) {
2430
0
    auto &&Info = DSAStack->isLoopControlVariable(D);
2431
0
    if (Info.first ||
2432
0
        (VD && VD->hasLocalStorage() &&
2433
0
         isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2434
0
        (VD && DSAStack->isForceVarCapturing()))
2435
0
      return VD ? VD : Info.second;
2436
0
    DSAStackTy::DSAVarData DVarTop =
2437
0
        DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2438
0
    if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2439
0
        (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2440
0
      return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2441
    // Threadprivate variables must not be captured.
2442
0
    if (isOpenMPThreadPrivate(DVarTop.CKind))
2443
0
      return nullptr;
2444
    // The variable is not private or it is the variable in the directive with
2445
    // default(none) clause and not used in any clause.
2446
0
    DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2447
0
        D,
2448
0
        [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
2449
0
          return isOpenMPPrivate(C) && !AppliedToPointee;
2450
0
        },
2451
0
        [](OpenMPDirectiveKind) { return true; },
2452
0
        DSAStack->isClauseParsingMode());
2453
    // Global shared must not be captured.
2454
0
    if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2455
0
        ((DSAStack->getDefaultDSA() != DSA_none &&
2456
0
          DSAStack->getDefaultDSA() != DSA_private &&
2457
0
          DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2458
0
         DVarTop.CKind == OMPC_shared))
2459
0
      return nullptr;
2460
0
    auto *FD = dyn_cast<FieldDecl>(D);
2461
0
    if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2462
0
        !DVarPrivate.PrivateCopy) {
2463
0
      DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2464
0
          D,
2465
0
          [](OpenMPClauseKind C, bool AppliedToPointee,
2466
0
             DefaultDataSharingAttributes DefaultAttr) {
2467
0
            return isOpenMPPrivate(C) && !AppliedToPointee &&
2468
0
                   (DefaultAttr == DSA_firstprivate ||
2469
0
                    DefaultAttr == DSA_private);
2470
0
          },
2471
0
          [](OpenMPDirectiveKind) { return true; },
2472
0
          DSAStack->isClauseParsingMode());
2473
0
      if (DVarPrivate.CKind == OMPC_unknown)
2474
0
        return nullptr;
2475
2476
0
      VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD);
2477
0
      if (VD)
2478
0
        return VD;
2479
0
      if (getCurrentThisType().isNull())
2480
0
        return nullptr;
2481
0
      Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
2482
0
                                        /*IsImplicit=*/true);
2483
0
      const CXXScopeSpec CS = CXXScopeSpec();
2484
0
      Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(),
2485
0
                                 NestedNameSpecifierLoc(), SourceLocation(), FD,
2486
0
                                 DeclAccessPair::make(FD, FD->getAccess()),
2487
0
                                 /*HadMultipleCandidates=*/false,
2488
0
                                 DeclarationNameInfo(), FD->getType(),
2489
0
                                 VK_LValue, OK_Ordinary);
2490
0
      OMPCapturedExprDecl *CD = buildCaptureDecl(
2491
0
          *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2492
0
          CurContext->getParent(), /*AsExpression=*/false);
2493
0
      DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
2494
0
          *this, CD, CD->getType().getNonReferenceType(), SourceLocation());
2495
0
      VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
2496
0
      DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2497
0
      return VD;
2498
0
    }
2499
0
    if (DVarPrivate.CKind != OMPC_unknown ||
2500
0
        (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2501
0
                DSAStack->getDefaultDSA() == DSA_private ||
2502
0
                DSAStack->getDefaultDSA() == DSA_firstprivate)))
2503
0
      return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2504
0
  }
2505
0
  return nullptr;
2506
0
}
2507
2508
void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2509
0
                                        unsigned Level) const {
2510
0
  FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2511
0
}
2512
2513
0
void Sema::startOpenMPLoop() {
2514
0
  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2515
0
  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2516
0
    DSAStack->loopInit();
2517
0
}
2518
2519
0
void Sema::startOpenMPCXXRangeFor() {
2520
0
  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2521
0
  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2522
0
    DSAStack->resetPossibleLoopCounter();
2523
0
    DSAStack->loopStart();
2524
0
  }
2525
0
}
2526
2527
OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2528
0
                                           unsigned CapLevel) const {
2529
0
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2530
0
  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2531
0
      (!DSAStack->isClauseParsingMode() ||
2532
0
       DSAStack->getParentDirective() != OMPD_unknown)) {
2533
0
    DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2534
0
        D,
2535
0
        [](OpenMPClauseKind C, bool AppliedToPointee,
2536
0
           DefaultDataSharingAttributes DefaultAttr) {
2537
0
          return isOpenMPPrivate(C) && !AppliedToPointee &&
2538
0
                 DefaultAttr == DSA_private;
2539
0
        },
2540
0
        [](OpenMPDirectiveKind) { return true; },
2541
0
        DSAStack->isClauseParsingMode());
2542
0
    if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2543
0
        DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2544
0
        !DSAStack->isLoopControlVariable(D).first)
2545
0
      return OMPC_private;
2546
0
  }
2547
0
  if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2548
0
    bool IsTriviallyCopyable =
2549
0
        D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2550
0
        !D->getType()
2551
0
             .getNonReferenceType()
2552
0
             .getCanonicalType()
2553
0
             ->getAsCXXRecordDecl();
2554
0
    OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2555
0
    SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2556
0
    getOpenMPCaptureRegions(CaptureRegions, DKind);
2557
0
    if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2558
0
        (IsTriviallyCopyable ||
2559
0
         !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2560
0
      if (DSAStack->hasExplicitDSA(
2561
0
              D,
2562
0
              [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2563
0
              Level, /*NotLastprivate=*/true))
2564
0
        return OMPC_firstprivate;
2565
0
      DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2566
0
      if (DVar.CKind != OMPC_shared &&
2567
0
          !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2568
0
        DSAStack->addImplicitTaskFirstprivate(Level, D);
2569
0
        return OMPC_firstprivate;
2570
0
      }
2571
0
    }
2572
0
  }
2573
0
  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()) &&
2574
0
      !isOpenMPLoopTransformationDirective(DSAStack->getCurrentDirective())) {
2575
0
    if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) {
2576
0
      DSAStack->resetPossibleLoopCounter(D);
2577
0
      DSAStack->loopStart();
2578
0
      return OMPC_private;
2579
0
    }
2580
0
    if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2581
0
         DSAStack->isLoopControlVariable(D).first) &&
2582
0
        !DSAStack->hasExplicitDSA(
2583
0
            D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2584
0
            Level) &&
2585
0
        !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2586
0
      return OMPC_private;
2587
0
  }
2588
0
  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2589
0
    if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2590
0
        DSAStack->isForceVarCapturing() &&
2591
0
        !DSAStack->hasExplicitDSA(
2592
0
            D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2593
0
            Level))
2594
0
      return OMPC_private;
2595
0
  }
2596
  // User-defined allocators are private since they must be defined in the
2597
  // context of target region.
2598
0
  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2599
0
      DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2600
0
          DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2601
0
          DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2602
0
    return OMPC_private;
2603
0
  return (DSAStack->hasExplicitDSA(
2604
0
              D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2605
0
              Level) ||
2606
0
          (DSAStack->isClauseParsingMode() &&
2607
0
           DSAStack->getClauseParsingMode() == OMPC_private) ||
2608
          // Consider taskgroup reduction descriptor variable a private
2609
          // to avoid possible capture in the region.
2610
0
          (DSAStack->hasExplicitDirective(
2611
0
               [](OpenMPDirectiveKind K) {
2612
0
                 return K == OMPD_taskgroup ||
2613
0
                        ((isOpenMPParallelDirective(K) ||
2614
0
                          isOpenMPWorksharingDirective(K)) &&
2615
0
                         !isOpenMPSimdDirective(K));
2616
0
               },
2617
0
               Level) &&
2618
0
           DSAStack->isTaskgroupReductionRef(D, Level)))
2619
0
             ? OMPC_private
2620
0
             : OMPC_unknown;
2621
0
}
2622
2623
void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2624
0
                                unsigned Level) {
2625
0
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2626
0
  D = getCanonicalDecl(D);
2627
0
  OpenMPClauseKind OMPC = OMPC_unknown;
2628
0
  for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2629
0
    const unsigned NewLevel = I - 1;
2630
0
    if (DSAStack->hasExplicitDSA(
2631
0
            D,
2632
0
            [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2633
0
              if (isOpenMPPrivate(K) && !AppliedToPointee) {
2634
0
                OMPC = K;
2635
0
                return true;
2636
0
              }
2637
0
              return false;
2638
0
            },
2639
0
            NewLevel))
2640
0
      break;
2641
0
    if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2642
0
            D, NewLevel,
2643
0
            [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2644
0
               OpenMPClauseKind) { return true; })) {
2645
0
      OMPC = OMPC_map;
2646
0
      break;
2647
0
    }
2648
0
    if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2649
0
                                       NewLevel)) {
2650
0
      OMPC = OMPC_map;
2651
0
      if (DSAStack->mustBeFirstprivateAtLevel(
2652
0
              NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2653
0
        OMPC = OMPC_firstprivate;
2654
0
      break;
2655
0
    }
2656
0
  }
2657
0
  if (OMPC != OMPC_unknown)
2658
0
    FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2659
0
}
2660
2661
bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2662
0
                                      unsigned CaptureLevel) const {
2663
0
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2664
  // Return true if the current level is no longer enclosed in a target region.
2665
2666
0
  SmallVector<OpenMPDirectiveKind, 4> Regions;
2667
0
  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2668
0
  const auto *VD = dyn_cast<VarDecl>(D);
2669
0
  return VD && !VD->hasLocalStorage() &&
2670
0
         DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2671
0
                                        Level) &&
2672
0
         Regions[CaptureLevel] != OMPD_task;
2673
0
}
2674
2675
bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2676
0
                                      unsigned CaptureLevel) const {
2677
0
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2678
  // Return true if the current level is no longer enclosed in a target region.
2679
2680
0
  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2681
0
    if (!VD->hasLocalStorage()) {
2682
0
      if (isInOpenMPTargetExecutionDirective())
2683
0
        return true;
2684
0
      DSAStackTy::DSAVarData TopDVar =
2685
0
          DSAStack->getTopDSA(D, /*FromParent=*/false);
2686
0
      unsigned NumLevels =
2687
0
          getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2688
0
      if (Level == 0)
2689
        // non-file scope static variale with default(firstprivate)
2690
        // should be gloabal captured.
2691
0
        return (NumLevels == CaptureLevel + 1 &&
2692
0
                (TopDVar.CKind != OMPC_shared ||
2693
0
                 DSAStack->getDefaultDSA() == DSA_firstprivate));
2694
0
      do {
2695
0
        --Level;
2696
0
        DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2697
0
        if (DVar.CKind != OMPC_shared)
2698
0
          return true;
2699
0
      } while (Level > 0);
2700
0
    }
2701
0
  }
2702
0
  return true;
2703
0
}
2704
2705
46
void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2706
2707
void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2708
0
                                          OMPTraitInfo &TI) {
2709
0
  OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2710
0
}
2711
2712
0
void Sema::ActOnOpenMPEndDeclareVariant() {
2713
0
  assert(isInOpenMPDeclareVariantScope() &&
2714
0
         "Not in OpenMP declare variant scope!");
2715
2716
0
  OMPDeclareVariantScopes.pop_back();
2717
0
}
2718
2719
void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2720
                                         const FunctionDecl *Callee,
2721
0
                                         SourceLocation Loc) {
2722
0
  assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2723
0
  std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2724
0
      OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2725
  // Ignore host functions during device analyzis.
2726
0
  if (LangOpts.OpenMPIsTargetDevice &&
2727
0
      (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2728
0
    return;
2729
  // Ignore nohost functions during host analyzis.
2730
0
  if (!LangOpts.OpenMPIsTargetDevice && DevTy &&
2731
0
      *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2732
0
    return;
2733
0
  const FunctionDecl *FD = Callee->getMostRecentDecl();
2734
0
  DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2735
0
  if (LangOpts.OpenMPIsTargetDevice && DevTy &&
2736
0
      *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2737
    // Diagnose host function called during device codegen.
2738
0
    StringRef HostDevTy =
2739
0
        getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2740
0
    Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2741
0
    Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2742
0
         diag::note_omp_marked_device_type_here)
2743
0
        << HostDevTy;
2744
0
    return;
2745
0
  }
2746
0
  if (!LangOpts.OpenMPIsTargetDevice && !LangOpts.OpenMPOffloadMandatory &&
2747
0
      DevTy && *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2748
    // In OpenMP 5.2 or later, if the function has a host variant then allow
2749
    // that to be called instead
2750
0
    auto &&HasHostAttr = [](const FunctionDecl *Callee) {
2751
0
      for (OMPDeclareVariantAttr *A :
2752
0
           Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2753
0
        auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2754
0
        auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2755
0
        std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2756
0
            OMPDeclareTargetDeclAttr::getDeviceType(
2757
0
                VariantFD->getMostRecentDecl());
2758
0
        if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2759
0
          return true;
2760
0
      }
2761
0
      return false;
2762
0
    };
2763
0
    if (getLangOpts().OpenMP >= 52 &&
2764
0
        Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2765
0
      return;
2766
    // Diagnose nohost function called during host codegen.
2767
0
    StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2768
0
        OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2769
0
    Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2770
0
    Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2771
0
         diag::note_omp_marked_device_type_here)
2772
0
        << NoHostDevTy;
2773
0
  }
2774
0
}
2775
2776
void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2777
                               const DeclarationNameInfo &DirName,
2778
0
                               Scope *CurScope, SourceLocation Loc) {
2779
0
  DSAStack->push(DKind, DirName, CurScope, Loc);
2780
0
  PushExpressionEvaluationContext(
2781
0
      ExpressionEvaluationContext::PotentiallyEvaluated);
2782
0
}
2783
2784
0
void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2785
0
  DSAStack->setClauseParsingMode(K);
2786
0
}
2787
2788
0
void Sema::EndOpenMPClause() {
2789
0
  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2790
0
  CleanupVarDeclMarking();
2791
0
}
2792
2793
static std::pair<ValueDecl *, bool>
2794
getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2795
               SourceRange &ERange, bool AllowArraySection = false,
2796
               StringRef DiagType = "");
2797
2798
/// Check consistency of the reduction clauses.
2799
static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2800
0
                                  ArrayRef<OMPClause *> Clauses) {
2801
0
  bool InscanFound = false;
2802
0
  SourceLocation InscanLoc;
2803
  // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2804
  // A reduction clause without the inscan reduction-modifier may not appear on
2805
  // a construct on which a reduction clause with the inscan reduction-modifier
2806
  // appears.
2807
0
  for (OMPClause *C : Clauses) {
2808
0
    if (C->getClauseKind() != OMPC_reduction)
2809
0
      continue;
2810
0
    auto *RC = cast<OMPReductionClause>(C);
2811
0
    if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2812
0
      InscanFound = true;
2813
0
      InscanLoc = RC->getModifierLoc();
2814
0
      continue;
2815
0
    }
2816
0
    if (RC->getModifier() == OMPC_REDUCTION_task) {
2817
      // OpenMP 5.0, 2.19.5.4 reduction Clause.
2818
      // A reduction clause with the task reduction-modifier may only appear on
2819
      // a parallel construct, a worksharing construct or a combined or
2820
      // composite construct for which any of the aforementioned constructs is a
2821
      // constituent construct and simd or loop are not constituent constructs.
2822
0
      OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2823
0
      if (!(isOpenMPParallelDirective(CurDir) ||
2824
0
            isOpenMPWorksharingDirective(CurDir)) ||
2825
0
          isOpenMPSimdDirective(CurDir))
2826
0
        S.Diag(RC->getModifierLoc(),
2827
0
               diag::err_omp_reduction_task_not_parallel_or_worksharing);
2828
0
      continue;
2829
0
    }
2830
0
  }
2831
0
  if (InscanFound) {
2832
0
    for (OMPClause *C : Clauses) {
2833
0
      if (C->getClauseKind() != OMPC_reduction)
2834
0
        continue;
2835
0
      auto *RC = cast<OMPReductionClause>(C);
2836
0
      if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2837
0
        S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2838
0
                   ? RC->getBeginLoc()
2839
0
                   : RC->getModifierLoc(),
2840
0
               diag::err_omp_inscan_reduction_expected);
2841
0
        S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2842
0
        continue;
2843
0
      }
2844
0
      for (Expr *Ref : RC->varlists()) {
2845
0
        assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2846
0
        SourceLocation ELoc;
2847
0
        SourceRange ERange;
2848
0
        Expr *SimpleRefExpr = Ref;
2849
0
        auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2850
0
                                  /*AllowArraySection=*/true);
2851
0
        ValueDecl *D = Res.first;
2852
0
        if (!D)
2853
0
          continue;
2854
0
        if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2855
0
          S.Diag(Ref->getExprLoc(),
2856
0
                 diag::err_omp_reduction_not_inclusive_exclusive)
2857
0
              << Ref->getSourceRange();
2858
0
        }
2859
0
      }
2860
0
    }
2861
0
  }
2862
0
}
2863
2864
static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2865
                                 ArrayRef<OMPClause *> Clauses);
2866
static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2867
                                 bool WithInit);
2868
2869
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2870
                              const ValueDecl *D,
2871
                              const DSAStackTy::DSAVarData &DVar,
2872
                              bool IsLoopIterVar = false);
2873
2874
0
void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2875
  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2876
  //  A variable of class type (or array thereof) that appears in a lastprivate
2877
  //  clause requires an accessible, unambiguous default constructor for the
2878
  //  class type, unless the list item is also specified in a firstprivate
2879
  //  clause.
2880
0
  if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2881
0
    for (OMPClause *C : D->clauses()) {
2882
0
      if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2883
0
        SmallVector<Expr *, 8> PrivateCopies;
2884
0
        for (Expr *DE : Clause->varlists()) {
2885
0
          if (DE->isValueDependent() || DE->isTypeDependent()) {
2886
0
            PrivateCopies.push_back(nullptr);
2887
0
            continue;
2888
0
          }
2889
0
          auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2890
0
          auto *VD = cast<VarDecl>(DRE->getDecl());
2891
0
          QualType Type = VD->getType().getNonReferenceType();
2892
0
          const DSAStackTy::DSAVarData DVar =
2893
0
              DSAStack->getTopDSA(VD, /*FromParent=*/false);
2894
0
          if (DVar.CKind == OMPC_lastprivate) {
2895
            // Generate helper private variable and initialize it with the
2896
            // default value. The address of the original variable is replaced
2897
            // by the address of the new private variable in CodeGen. This new
2898
            // variable is not added to IdResolver, so the code in the OpenMP
2899
            // region uses original variable for proper diagnostics.
2900
0
            VarDecl *VDPrivate = buildVarDecl(
2901
0
                *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2902
0
                VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2903
0
            ActOnUninitializedDecl(VDPrivate);
2904
0
            if (VDPrivate->isInvalidDecl()) {
2905
0
              PrivateCopies.push_back(nullptr);
2906
0
              continue;
2907
0
            }
2908
0
            PrivateCopies.push_back(buildDeclRefExpr(
2909
0
                *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2910
0
          } else {
2911
            // The variable is also a firstprivate, so initialization sequence
2912
            // for private copy is generated already.
2913
0
            PrivateCopies.push_back(nullptr);
2914
0
          }
2915
0
        }
2916
0
        Clause->setPrivateCopies(PrivateCopies);
2917
0
        continue;
2918
0
      }
2919
      // Finalize nontemporal clause by handling private copies, if any.
2920
0
      if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2921
0
        SmallVector<Expr *, 8> PrivateRefs;
2922
0
        for (Expr *RefExpr : Clause->varlists()) {
2923
0
          assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2924
0
          SourceLocation ELoc;
2925
0
          SourceRange ERange;
2926
0
          Expr *SimpleRefExpr = RefExpr;
2927
0
          auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2928
0
          if (Res.second)
2929
            // It will be analyzed later.
2930
0
            PrivateRefs.push_back(RefExpr);
2931
0
          ValueDecl *D = Res.first;
2932
0
          if (!D)
2933
0
            continue;
2934
2935
0
          const DSAStackTy::DSAVarData DVar =
2936
0
              DSAStack->getTopDSA(D, /*FromParent=*/false);
2937
0
          PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2938
0
                                                 : SimpleRefExpr);
2939
0
        }
2940
0
        Clause->setPrivateRefs(PrivateRefs);
2941
0
        continue;
2942
0
      }
2943
0
      if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2944
0
        for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2945
0
          OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2946
0
          auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2947
0
          if (!DRE)
2948
0
            continue;
2949
0
          ValueDecl *VD = DRE->getDecl();
2950
0
          if (!VD || !isa<VarDecl>(VD))
2951
0
            continue;
2952
0
          DSAStackTy::DSAVarData DVar =
2953
0
              DSAStack->getTopDSA(VD, /*FromParent=*/false);
2954
          // OpenMP [2.12.5, target Construct]
2955
          // Memory allocators that appear in a uses_allocators clause cannot
2956
          // appear in other data-sharing attribute clauses or data-mapping
2957
          // attribute clauses in the same construct.
2958
0
          Expr *MapExpr = nullptr;
2959
0
          if (DVar.RefExpr ||
2960
0
              DSAStack->checkMappableExprComponentListsForDecl(
2961
0
                  VD, /*CurrentRegionOnly=*/true,
2962
0
                  [VD, &MapExpr](
2963
0
                      OMPClauseMappableExprCommon::MappableExprComponentListRef
2964
0
                          MapExprComponents,
2965
0
                      OpenMPClauseKind C) {
2966
0
                    auto MI = MapExprComponents.rbegin();
2967
0
                    auto ME = MapExprComponents.rend();
2968
0
                    if (MI != ME &&
2969
0
                        MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2970
0
                            VD->getCanonicalDecl()) {
2971
0
                      MapExpr = MI->getAssociatedExpression();
2972
0
                      return true;
2973
0
                    }
2974
0
                    return false;
2975
0
                  })) {
2976
0
            Diag(D.Allocator->getExprLoc(),
2977
0
                 diag::err_omp_allocator_used_in_clauses)
2978
0
                << D.Allocator->getSourceRange();
2979
0
            if (DVar.RefExpr)
2980
0
              reportOriginalDsa(*this, DSAStack, VD, DVar);
2981
0
            else
2982
0
              Diag(MapExpr->getExprLoc(), diag::note_used_here)
2983
0
                  << MapExpr->getSourceRange();
2984
0
          }
2985
0
        }
2986
0
        continue;
2987
0
      }
2988
0
    }
2989
    // Check allocate clauses.
2990
0
    if (!CurContext->isDependentContext())
2991
0
      checkAllocateClauses(*this, DSAStack, D->clauses());
2992
0
    checkReductionClauses(*this, DSAStack, D->clauses());
2993
0
  }
2994
2995
0
  DSAStack->pop();
2996
0
  DiscardCleanupsInEvaluationContext();
2997
0
  PopExpressionEvaluationContext();
2998
0
}
2999
3000
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
3001
                                     Expr *NumIterations, Sema &SemaRef,
3002
                                     Scope *S, DSAStackTy *Stack);
3003
3004
namespace {
3005
3006
class VarDeclFilterCCC final : public CorrectionCandidateCallback {
3007
private:
3008
  Sema &SemaRef;
3009
3010
public:
3011
0
  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
3012
0
  bool ValidateCandidate(const TypoCorrection &Candidate) override {
3013
0
    NamedDecl *ND = Candidate.getCorrectionDecl();
3014
0
    if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3015
0
      return VD->hasGlobalStorage() &&
3016
0
             SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3017
0
                                   SemaRef.getCurScope());
3018
0
    }
3019
0
    return false;
3020
0
  }
3021
3022
0
  std::unique_ptr<CorrectionCandidateCallback> clone() override {
3023
0
    return std::make_unique<VarDeclFilterCCC>(*this);
3024
0
  }
3025
};
3026
3027
class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
3028
private:
3029
  Sema &SemaRef;
3030
3031
public:
3032
0
  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
3033
0
  bool ValidateCandidate(const TypoCorrection &Candidate) override {
3034
0
    NamedDecl *ND = Candidate.getCorrectionDecl();
3035
0
    if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
3036
0
               isa<FunctionDecl>(ND))) {
3037
0
      return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3038
0
                                   SemaRef.getCurScope());
3039
0
    }
3040
0
    return false;
3041
0
  }
3042
3043
0
  std::unique_ptr<CorrectionCandidateCallback> clone() override {
3044
0
    return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
3045
0
  }
3046
};
3047
3048
} // namespace
3049
3050
ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
3051
                                         CXXScopeSpec &ScopeSpec,
3052
                                         const DeclarationNameInfo &Id,
3053
0
                                         OpenMPDirectiveKind Kind) {
3054
0
  LookupResult Lookup(*this, Id, LookupOrdinaryName);
3055
0
  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
3056
3057
0
  if (Lookup.isAmbiguous())
3058
0
    return ExprError();
3059
3060
0
  VarDecl *VD;
3061
0
  if (!Lookup.isSingleResult()) {
3062
0
    VarDeclFilterCCC CCC(*this);
3063
0
    if (TypoCorrection Corrected =
3064
0
            CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
3065
0
                        CTK_ErrorRecovery)) {
3066
0
      diagnoseTypo(Corrected,
3067
0
                   PDiag(Lookup.empty()
3068
0
                             ? diag::err_undeclared_var_use_suggest
3069
0
                             : diag::err_omp_expected_var_arg_suggest)
3070
0
                       << Id.getName());
3071
0
      VD = Corrected.getCorrectionDeclAs<VarDecl>();
3072
0
    } else {
3073
0
      Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
3074
0
                                       : diag::err_omp_expected_var_arg)
3075
0
          << Id.getName();
3076
0
      return ExprError();
3077
0
    }
3078
0
  } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
3079
0
    Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
3080
0
    Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
3081
0
    return ExprError();
3082
0
  }
3083
0
  Lookup.suppressDiagnostics();
3084
3085
  // OpenMP [2.9.2, Syntax, C/C++]
3086
  //   Variables must be file-scope, namespace-scope, or static block-scope.
3087
0
  if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
3088
0
    Diag(Id.getLoc(), diag::err_omp_global_var_arg)
3089
0
        << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
3090
0
    bool IsDecl =
3091
0
        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3092
0
    Diag(VD->getLocation(),
3093
0
         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3094
0
        << VD;
3095
0
    return ExprError();
3096
0
  }
3097
3098
0
  VarDecl *CanonicalVD = VD->getCanonicalDecl();
3099
0
  NamedDecl *ND = CanonicalVD;
3100
  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
3101
  //   A threadprivate directive for file-scope variables must appear outside
3102
  //   any definition or declaration.
3103
0
  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
3104
0
      !getCurLexicalContext()->isTranslationUnit()) {
3105
0
    Diag(Id.getLoc(), diag::err_omp_var_scope)
3106
0
        << getOpenMPDirectiveName(Kind) << VD;
3107
0
    bool IsDecl =
3108
0
        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3109
0
    Diag(VD->getLocation(),
3110
0
         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3111
0
        << VD;
3112
0
    return ExprError();
3113
0
  }
3114
  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
3115
  //   A threadprivate directive for static class member variables must appear
3116
  //   in the class definition, in the same scope in which the member
3117
  //   variables are declared.
3118
0
  if (CanonicalVD->isStaticDataMember() &&
3119
0
      !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
3120
0
    Diag(Id.getLoc(), diag::err_omp_var_scope)
3121
0
        << getOpenMPDirectiveName(Kind) << VD;
3122
0
    bool IsDecl =
3123
0
        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3124
0
    Diag(VD->getLocation(),
3125
0
         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3126
0
        << VD;
3127
0
    return ExprError();
3128
0
  }
3129
  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
3130
  //   A threadprivate directive for namespace-scope variables must appear
3131
  //   outside any definition or declaration other than the namespace
3132
  //   definition itself.
3133
0
  if (CanonicalVD->getDeclContext()->isNamespace() &&
3134
0
      (!getCurLexicalContext()->isFileContext() ||
3135
0
       !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
3136
0
    Diag(Id.getLoc(), diag::err_omp_var_scope)
3137
0
        << getOpenMPDirectiveName(Kind) << VD;
3138
0
    bool IsDecl =
3139
0
        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3140
0
    Diag(VD->getLocation(),
3141
0
         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3142
0
        << VD;
3143
0
    return ExprError();
3144
0
  }
3145
  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
3146
  //   A threadprivate directive for static block-scope variables must appear
3147
  //   in the scope of the variable and not in a nested scope.
3148
0
  if (CanonicalVD->isLocalVarDecl() && CurScope &&
3149
0
      !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
3150
0
    Diag(Id.getLoc(), diag::err_omp_var_scope)
3151
0
        << getOpenMPDirectiveName(Kind) << VD;
3152
0
    bool IsDecl =
3153
0
        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3154
0
    Diag(VD->getLocation(),
3155
0
         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3156
0
        << VD;
3157
0
    return ExprError();
3158
0
  }
3159
3160
  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
3161
  //   A threadprivate directive must lexically precede all references to any
3162
  //   of the variables in its list.
3163
0
  if (Kind == OMPD_threadprivate && VD->isUsed() &&
3164
0
      !DSAStack->isThreadPrivate(VD)) {
3165
0
    Diag(Id.getLoc(), diag::err_omp_var_used)
3166
0
        << getOpenMPDirectiveName(Kind) << VD;
3167
0
    return ExprError();
3168
0
  }
3169
3170
0
  QualType ExprType = VD->getType().getNonReferenceType();
3171
0
  return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
3172
0
                             SourceLocation(), VD,
3173
0
                             /*RefersToEnclosingVariableOrCapture=*/false,
3174
0
                             Id.getLoc(), ExprType, VK_LValue);
3175
0
}
3176
3177
Sema::DeclGroupPtrTy
3178
Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
3179
0
                                        ArrayRef<Expr *> VarList) {
3180
0
  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
3181
0
    CurContext->addDecl(D);
3182
0
    return DeclGroupPtrTy::make(DeclGroupRef(D));
3183
0
  }
3184
0
  return nullptr;
3185
0
}
3186
3187
namespace {
3188
class LocalVarRefChecker final
3189
    : public ConstStmtVisitor<LocalVarRefChecker, bool> {
3190
  Sema &SemaRef;
3191
3192
public:
3193
0
  bool VisitDeclRefExpr(const DeclRefExpr *E) {
3194
0
    if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3195
0
      if (VD->hasLocalStorage()) {
3196
0
        SemaRef.Diag(E->getBeginLoc(),
3197
0
                     diag::err_omp_local_var_in_threadprivate_init)
3198
0
            << E->getSourceRange();
3199
0
        SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
3200
0
            << VD << VD->getSourceRange();
3201
0
        return true;
3202
0
      }
3203
0
    }
3204
0
    return false;
3205
0
  }
3206
0
  bool VisitStmt(const Stmt *S) {
3207
0
    for (const Stmt *Child : S->children()) {
3208
0
      if (Child && Visit(Child))
3209
0
        return true;
3210
0
    }
3211
0
    return false;
3212
0
  }
3213
0
  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
3214
};
3215
} // namespace
3216
3217
OMPThreadPrivateDecl *
3218
0
Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
3219
0
  SmallVector<Expr *, 8> Vars;
3220
0
  for (Expr *RefExpr : VarList) {
3221
0
    auto *DE = cast<DeclRefExpr>(RefExpr);
3222
0
    auto *VD = cast<VarDecl>(DE->getDecl());
3223
0
    SourceLocation ILoc = DE->getExprLoc();
3224
3225
    // Mark variable as used.
3226
0
    VD->setReferenced();
3227
0
    VD->markUsed(Context);
3228
3229
0
    QualType QType = VD->getType();
3230
0
    if (QType->isDependentType() || QType->isInstantiationDependentType()) {
3231
      // It will be analyzed later.
3232
0
      Vars.push_back(DE);
3233
0
      continue;
3234
0
    }
3235
3236
    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3237
    //   A threadprivate variable must not have an incomplete type.
3238
0
    if (RequireCompleteType(ILoc, VD->getType(),
3239
0
                            diag::err_omp_threadprivate_incomplete_type)) {
3240
0
      continue;
3241
0
    }
3242
3243
    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3244
    //   A threadprivate variable must not have a reference type.
3245
0
    if (VD->getType()->isReferenceType()) {
3246
0
      Diag(ILoc, diag::err_omp_ref_type_arg)
3247
0
          << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3248
0
      bool IsDecl =
3249
0
          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3250
0
      Diag(VD->getLocation(),
3251
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3252
0
          << VD;
3253
0
      continue;
3254
0
    }
3255
3256
    // Check if this is a TLS variable. If TLS is not being supported, produce
3257
    // the corresponding diagnostic.
3258
0
    if ((VD->getTLSKind() != VarDecl::TLS_None &&
3259
0
         !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3260
0
           getLangOpts().OpenMPUseTLS &&
3261
0
           getASTContext().getTargetInfo().isTLSSupported())) ||
3262
0
        (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3263
0
         !VD->isLocalVarDecl())) {
3264
0
      Diag(ILoc, diag::err_omp_var_thread_local)
3265
0
          << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3266
0
      bool IsDecl =
3267
0
          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3268
0
      Diag(VD->getLocation(),
3269
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3270
0
          << VD;
3271
0
      continue;
3272
0
    }
3273
3274
    // Check if initial value of threadprivate variable reference variable with
3275
    // local storage (it is not supported by runtime).
3276
0
    if (const Expr *Init = VD->getAnyInitializer()) {
3277
0
      LocalVarRefChecker Checker(*this);
3278
0
      if (Checker.Visit(Init))
3279
0
        continue;
3280
0
    }
3281
3282
0
    Vars.push_back(RefExpr);
3283
0
    DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3284
0
    VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3285
0
        Context, SourceRange(Loc, Loc)));
3286
0
    if (ASTMutationListener *ML = Context.getASTMutationListener())
3287
0
      ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3288
0
  }
3289
0
  OMPThreadPrivateDecl *D = nullptr;
3290
0
  if (!Vars.empty()) {
3291
0
    D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3292
0
                                     Vars);
3293
0
    D->setAccess(AS_public);
3294
0
  }
3295
0
  return D;
3296
0
}
3297
3298
static OMPAllocateDeclAttr::AllocatorTypeTy
3299
0
getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3300
0
  if (!Allocator)
3301
0
    return OMPAllocateDeclAttr::OMPNullMemAlloc;
3302
0
  if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3303
0
      Allocator->isInstantiationDependent() ||
3304
0
      Allocator->containsUnexpandedParameterPack())
3305
0
    return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3306
0
  auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3307
0
  llvm::FoldingSetNodeID AEId;
3308
0
  const Expr *AE = Allocator->IgnoreParenImpCasts();
3309
0
  AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3310
0
  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3311
0
    auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3312
0
    const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3313
0
    llvm::FoldingSetNodeID DAEId;
3314
0
    DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
3315
0
                                            /*Canonical=*/true);
3316
0
    if (AEId == DAEId) {
3317
0
      AllocatorKindRes = AllocatorKind;
3318
0
      break;
3319
0
    }
3320
0
  }
3321
0
  return AllocatorKindRes;
3322
0
}
3323
3324
static bool checkPreviousOMPAllocateAttribute(
3325
    Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3326
0
    OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3327
0
  if (!VD->hasAttr<OMPAllocateDeclAttr>())
3328
0
    return false;
3329
0
  const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3330
0
  Expr *PrevAllocator = A->getAllocator();
3331
0
  OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3332
0
      getAllocatorKind(S, Stack, PrevAllocator);
3333
0
  bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3334
0
  if (AllocatorsMatch &&
3335
0
      AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3336
0
      Allocator && PrevAllocator) {
3337
0
    const Expr *AE = Allocator->IgnoreParenImpCasts();
3338
0
    const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3339
0
    llvm::FoldingSetNodeID AEId, PAEId;
3340
0
    AE->Profile(AEId, S.Context, /*Canonical=*/true);
3341
0
    PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3342
0
    AllocatorsMatch = AEId == PAEId;
3343
0
  }
3344
0
  if (!AllocatorsMatch) {
3345
0
    SmallString<256> AllocatorBuffer;
3346
0
    llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3347
0
    if (Allocator)
3348
0
      Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3349
0
    SmallString<256> PrevAllocatorBuffer;
3350
0
    llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3351
0
    if (PrevAllocator)
3352
0
      PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3353
0
                                 S.getPrintingPolicy());
3354
3355
0
    SourceLocation AllocatorLoc =
3356
0
        Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3357
0
    SourceRange AllocatorRange =
3358
0
        Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3359
0
    SourceLocation PrevAllocatorLoc =
3360
0
        PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3361
0
    SourceRange PrevAllocatorRange =
3362
0
        PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3363
0
    S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3364
0
        << (Allocator ? 1 : 0) << AllocatorStream.str()
3365
0
        << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3366
0
        << AllocatorRange;
3367
0
    S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3368
0
        << PrevAllocatorRange;
3369
0
    return true;
3370
0
  }
3371
0
  return false;
3372
0
}
3373
3374
static void
3375
applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3376
                          OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3377
0
                          Expr *Allocator, Expr *Alignment, SourceRange SR) {
3378
0
  if (VD->hasAttr<OMPAllocateDeclAttr>())
3379
0
    return;
3380
0
  if (Alignment &&
3381
0
      (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3382
0
       Alignment->isInstantiationDependent() ||
3383
0
       Alignment->containsUnexpandedParameterPack()))
3384
    // Apply later when we have a usable value.
3385
0
    return;
3386
0
  if (Allocator &&
3387
0
      (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3388
0
       Allocator->isInstantiationDependent() ||
3389
0
       Allocator->containsUnexpandedParameterPack()))
3390
0
    return;
3391
0
  auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3392
0
                                                Allocator, Alignment, SR);
3393
0
  VD->addAttr(A);
3394
0
  if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3395
0
    ML->DeclarationMarkedOpenMPAllocate(VD, A);
3396
0
}
3397
3398
Sema::DeclGroupPtrTy
3399
Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
3400
                                   ArrayRef<OMPClause *> Clauses,
3401
0
                                   DeclContext *Owner) {
3402
0
  assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3403
0
  Expr *Alignment = nullptr;
3404
0
  Expr *Allocator = nullptr;
3405
0
  if (Clauses.empty()) {
3406
    // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3407
    // allocate directives that appear in a target region must specify an
3408
    // allocator clause unless a requires directive with the dynamic_allocators
3409
    // clause is present in the same compilation unit.
3410
0
    if (LangOpts.OpenMPIsTargetDevice &&
3411
0
        !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3412
0
      targetDiag(Loc, diag::err_expected_allocator_clause);
3413
0
  } else {
3414
0
    for (const OMPClause *C : Clauses)
3415
0
      if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3416
0
        Allocator = AC->getAllocator();
3417
0
      else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3418
0
        Alignment = AC->getAlignment();
3419
0
      else
3420
0
        llvm_unreachable("Unexpected clause on allocate directive");
3421
0
  }
3422
0
  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3423
0
      getAllocatorKind(*this, DSAStack, Allocator);
3424
0
  SmallVector<Expr *, 8> Vars;
3425
0
  for (Expr *RefExpr : VarList) {
3426
0
    auto *DE = cast<DeclRefExpr>(RefExpr);
3427
0
    auto *VD = cast<VarDecl>(DE->getDecl());
3428
3429
    // Check if this is a TLS variable or global register.
3430
0
    if (VD->getTLSKind() != VarDecl::TLS_None ||
3431
0
        VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3432
0
        (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3433
0
         !VD->isLocalVarDecl()))
3434
0
      continue;
3435
3436
    // If the used several times in the allocate directive, the same allocator
3437
    // must be used.
3438
0
    if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3439
0
                                          AllocatorKind, Allocator))
3440
0
      continue;
3441
3442
    // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3443
    // If a list item has a static storage type, the allocator expression in the
3444
    // allocator clause must be a constant expression that evaluates to one of
3445
    // the predefined memory allocator values.
3446
0
    if (Allocator && VD->hasGlobalStorage()) {
3447
0
      if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3448
0
        Diag(Allocator->getExprLoc(),
3449
0
             diag::err_omp_expected_predefined_allocator)
3450
0
            << Allocator->getSourceRange();
3451
0
        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3452
0
                      VarDecl::DeclarationOnly;
3453
0
        Diag(VD->getLocation(),
3454
0
             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3455
0
            << VD;
3456
0
        continue;
3457
0
      }
3458
0
    }
3459
3460
0
    Vars.push_back(RefExpr);
3461
0
    applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3462
0
                              DE->getSourceRange());
3463
0
  }
3464
0
  if (Vars.empty())
3465
0
    return nullptr;
3466
0
  if (!Owner)
3467
0
    Owner = getCurLexicalContext();
3468
0
  auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3469
0
  D->setAccess(AS_public);
3470
0
  Owner->addDecl(D);
3471
0
  return DeclGroupPtrTy::make(DeclGroupRef(D));
3472
0
}
3473
3474
Sema::DeclGroupPtrTy
3475
Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3476
0
                                   ArrayRef<OMPClause *> ClauseList) {
3477
0
  OMPRequiresDecl *D = nullptr;
3478
0
  if (!CurContext->isFileContext()) {
3479
0
    Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3480
0
  } else {
3481
0
    D = CheckOMPRequiresDecl(Loc, ClauseList);
3482
0
    if (D) {
3483
0
      CurContext->addDecl(D);
3484
0
      DSAStack->addRequiresDecl(D);
3485
0
    }
3486
0
  }
3487
0
  return DeclGroupPtrTy::make(DeclGroupRef(D));
3488
0
}
3489
3490
void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3491
                                       OpenMPDirectiveKind DKind,
3492
                                       ArrayRef<std::string> Assumptions,
3493
0
                                       bool SkippedClauses) {
3494
0
  if (!SkippedClauses && Assumptions.empty())
3495
0
    Diag(Loc, diag::err_omp_no_clause_for_directive)
3496
0
        << llvm::omp::getAllAssumeClauseOptions()
3497
0
        << llvm::omp::getOpenMPDirectiveName(DKind);
3498
3499
0
  auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3500
0
  if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3501
0
    OMPAssumeScoped.push_back(AA);
3502
0
    return;
3503
0
  }
3504
3505
  // Global assumes without assumption clauses are ignored.
3506
0
  if (Assumptions.empty())
3507
0
    return;
3508
3509
0
  assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3510
0
         "Unexpected omp assumption directive!");
3511
0
  OMPAssumeGlobal.push_back(AA);
3512
3513
  // The OMPAssumeGlobal scope above will take care of new declarations but
3514
  // we also want to apply the assumption to existing ones, e.g., to
3515
  // declarations in included headers. To this end, we traverse all existing
3516
  // declaration contexts and annotate function declarations here.
3517
0
  SmallVector<DeclContext *, 8> DeclContexts;
3518
0
  auto *Ctx = CurContext;
3519
0
  while (Ctx->getLexicalParent())
3520
0
    Ctx = Ctx->getLexicalParent();
3521
0
  DeclContexts.push_back(Ctx);
3522
0
  while (!DeclContexts.empty()) {
3523
0
    DeclContext *DC = DeclContexts.pop_back_val();
3524
0
    for (auto *SubDC : DC->decls()) {
3525
0
      if (SubDC->isInvalidDecl())
3526
0
        continue;
3527
0
      if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3528
0
        DeclContexts.push_back(CTD->getTemplatedDecl());
3529
0
        llvm::append_range(DeclContexts, CTD->specializations());
3530
0
        continue;
3531
0
      }
3532
0
      if (auto *DC = dyn_cast<DeclContext>(SubDC))
3533
0
        DeclContexts.push_back(DC);
3534
0
      if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3535
0
        F->addAttr(AA);
3536
0
        continue;
3537
0
      }
3538
0
    }
3539
0
  }
3540
0
}
3541
3542
0
void Sema::ActOnOpenMPEndAssumesDirective() {
3543
0
  assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3544
0
  OMPAssumeScoped.pop_back();
3545
0
}
3546
3547
OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3548
0
                                            ArrayRef<OMPClause *> ClauseList) {
3549
  /// For target specific clauses, the requires directive cannot be
3550
  /// specified after the handling of any of the target regions in the
3551
  /// current compilation unit.
3552
0
  ArrayRef<SourceLocation> TargetLocations =
3553
0
      DSAStack->getEncounteredTargetLocs();
3554
0
  SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3555
0
  if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3556
0
    for (const OMPClause *CNew : ClauseList) {
3557
      // Check if any of the requires clauses affect target regions.
3558
0
      if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3559
0
          isa<OMPUnifiedAddressClause>(CNew) ||
3560
0
          isa<OMPReverseOffloadClause>(CNew) ||
3561
0
          isa<OMPDynamicAllocatorsClause>(CNew)) {
3562
0
        Diag(Loc, diag::err_omp_directive_before_requires)
3563
0
            << "target" << getOpenMPClauseName(CNew->getClauseKind());
3564
0
        for (SourceLocation TargetLoc : TargetLocations) {
3565
0
          Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3566
0
              << "target";
3567
0
        }
3568
0
      } else if (!AtomicLoc.isInvalid() &&
3569
0
                 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3570
0
        Diag(Loc, diag::err_omp_directive_before_requires)
3571
0
            << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3572
0
        Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3573
0
            << "atomic";
3574
0
      }
3575
0
    }
3576
0
  }
3577
3578
0
  if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3579
0
    return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3580
0
                                   ClauseList);
3581
0
  return nullptr;
3582
0
}
3583
3584
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3585
                              const ValueDecl *D,
3586
                              const DSAStackTy::DSAVarData &DVar,
3587
0
                              bool IsLoopIterVar) {
3588
0
  if (DVar.RefExpr) {
3589
0
    SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3590
0
        << getOpenMPClauseName(DVar.CKind);
3591
0
    return;
3592
0
  }
3593
0
  enum {
3594
0
    PDSA_StaticMemberShared,
3595
0
    PDSA_StaticLocalVarShared,
3596
0
    PDSA_LoopIterVarPrivate,
3597
0
    PDSA_LoopIterVarLinear,
3598
0
    PDSA_LoopIterVarLastprivate,
3599
0
    PDSA_ConstVarShared,
3600
0
    PDSA_GlobalVarShared,
3601
0
    PDSA_TaskVarFirstprivate,
3602
0
    PDSA_LocalVarPrivate,
3603
0
    PDSA_Implicit
3604
0
  } Reason = PDSA_Implicit;
3605
0
  bool ReportHint = false;
3606
0
  auto ReportLoc = D->getLocation();
3607
0
  auto *VD = dyn_cast<VarDecl>(D);
3608
0
  if (IsLoopIterVar) {
3609
0
    if (DVar.CKind == OMPC_private)
3610
0
      Reason = PDSA_LoopIterVarPrivate;
3611
0
    else if (DVar.CKind == OMPC_lastprivate)
3612
0
      Reason = PDSA_LoopIterVarLastprivate;
3613
0
    else
3614
0
      Reason = PDSA_LoopIterVarLinear;
3615
0
  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3616
0
             DVar.CKind == OMPC_firstprivate) {
3617
0
    Reason = PDSA_TaskVarFirstprivate;
3618
0
    ReportLoc = DVar.ImplicitDSALoc;
3619
0
  } else if (VD && VD->isStaticLocal())
3620
0
    Reason = PDSA_StaticLocalVarShared;
3621
0
  else if (VD && VD->isStaticDataMember())
3622
0
    Reason = PDSA_StaticMemberShared;
3623
0
  else if (VD && VD->isFileVarDecl())
3624
0
    Reason = PDSA_GlobalVarShared;
3625
0
  else if (D->getType().isConstant(SemaRef.getASTContext()))
3626
0
    Reason = PDSA_ConstVarShared;
3627
0
  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3628
0
    ReportHint = true;
3629
0
    Reason = PDSA_LocalVarPrivate;
3630
0
  }
3631
0
  if (Reason != PDSA_Implicit) {
3632
0
    SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3633
0
        << Reason << ReportHint
3634
0
        << getOpenMPDirectiveName(Stack->getCurrentDirective());
3635
0
  } else if (DVar.ImplicitDSALoc.isValid()) {
3636
0
    SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3637
0
        << getOpenMPClauseName(DVar.CKind);
3638
0
  }
3639
0
}
3640
3641
static OpenMPMapClauseKind
3642
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3643
0
                             bool IsAggregateOrDeclareTarget) {
3644
0
  OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3645
0
  switch (M) {
3646
0
  case OMPC_DEFAULTMAP_MODIFIER_alloc:
3647
0
    Kind = OMPC_MAP_alloc;
3648
0
    break;
3649
0
  case OMPC_DEFAULTMAP_MODIFIER_to:
3650
0
    Kind = OMPC_MAP_to;
3651
0
    break;
3652
0
  case OMPC_DEFAULTMAP_MODIFIER_from:
3653
0
    Kind = OMPC_MAP_from;
3654
0
    break;
3655
0
  case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3656
0
    Kind = OMPC_MAP_tofrom;
3657
0
    break;
3658
0
  case OMPC_DEFAULTMAP_MODIFIER_present:
3659
    // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3660
    // If implicit-behavior is present, each variable referenced in the
3661
    // construct in the category specified by variable-category is treated as if
3662
    // it had been listed in a map clause with the map-type of alloc and
3663
    // map-type-modifier of present.
3664
0
    Kind = OMPC_MAP_alloc;
3665
0
    break;
3666
0
  case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3667
0
  case OMPC_DEFAULTMAP_MODIFIER_last:
3668
0
    llvm_unreachable("Unexpected defaultmap implicit behavior");
3669
0
  case OMPC_DEFAULTMAP_MODIFIER_none:
3670
0
  case OMPC_DEFAULTMAP_MODIFIER_default:
3671
0
  case OMPC_DEFAULTMAP_MODIFIER_unknown:
3672
    // IsAggregateOrDeclareTarget could be true if:
3673
    // 1. the implicit behavior for aggregate is tofrom
3674
    // 2. it's a declare target link
3675
0
    if (IsAggregateOrDeclareTarget) {
3676
0
      Kind = OMPC_MAP_tofrom;
3677
0
      break;
3678
0
    }
3679
0
    llvm_unreachable("Unexpected defaultmap implicit behavior");
3680
0
  }
3681
0
  assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3682
0
  return Kind;
3683
0
}
3684
3685
namespace {
3686
class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3687
  DSAStackTy *Stack;
3688
  Sema &SemaRef;
3689
  bool ErrorFound = false;
3690
  bool TryCaptureCXXThisMembers = false;
3691
  CapturedStmt *CS = nullptr;
3692
  const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
3693
  llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3694
  llvm::SmallVector<Expr *, 4> ImplicitPrivate;
3695
  llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3696
  llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3697
      ImplicitMapModifier[DefaultmapKindNum];
3698
  Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3699
  llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3700
3701
0
  void VisitSubCaptures(OMPExecutableDirective *S) {
3702
    // Check implicitly captured variables.
3703
0
    if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3704
0
      return;
3705
0
    if (S->getDirectiveKind() == OMPD_atomic ||
3706
0
        S->getDirectiveKind() == OMPD_critical ||
3707
0
        S->getDirectiveKind() == OMPD_section ||
3708
0
        S->getDirectiveKind() == OMPD_master ||
3709
0
        S->getDirectiveKind() == OMPD_masked ||
3710
0
        S->getDirectiveKind() == OMPD_scope ||
3711
0
        isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3712
0
      Visit(S->getAssociatedStmt());
3713
0
      return;
3714
0
    }
3715
0
    visitSubCaptures(S->getInnermostCapturedStmt());
3716
    // Try to capture inner this->member references to generate correct mappings
3717
    // and diagnostics.
3718
0
    if (TryCaptureCXXThisMembers ||
3719
0
        (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3720
0
         llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3721
0
                      [](const CapturedStmt::Capture &C) {
3722
0
                        return C.capturesThis();
3723
0
                      }))) {
3724
0
      bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3725
0
      TryCaptureCXXThisMembers = true;
3726
0
      Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3727
0
      TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3728
0
    }
3729
    // In tasks firstprivates are not captured anymore, need to analyze them
3730
    // explicitly.
3731
0
    if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3732
0
        !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3733
0
      for (OMPClause *C : S->clauses())
3734
0
        if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3735
0
          for (Expr *Ref : FC->varlists())
3736
0
            Visit(Ref);
3737
0
        }
3738
0
    }
3739
0
  }
3740
3741
public:
3742
0
  void VisitDeclRefExpr(DeclRefExpr *E) {
3743
0
    if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3744
0
        E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3745
0
        E->isInstantiationDependent())
3746
0
      return;
3747
0
    if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3748
      // Check the datasharing rules for the expressions in the clauses.
3749
0
      if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3750
0
                  !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr &&
3751
0
                  !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3752
0
        if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3753
0
          if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3754
0
            Visit(CED->getInit());
3755
0
            return;
3756
0
          }
3757
0
      } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3758
        // Do not analyze internal variables and do not enclose them into
3759
        // implicit clauses.
3760
0
        if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3761
0
          return;
3762
0
      VD = VD->getCanonicalDecl();
3763
      // Skip internally declared variables.
3764
0
      if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3765
0
          !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3766
0
          !Stack->isImplicitTaskFirstprivate(VD))
3767
0
        return;
3768
      // Skip allocators in uses_allocators clauses.
3769
0
      if (Stack->isUsesAllocatorsDecl(VD))
3770
0
        return;
3771
3772
0
      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3773
      // Check if the variable has explicit DSA set and stop analysis if it so.
3774
0
      if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3775
0
        return;
3776
3777
      // Skip internally declared static variables.
3778
0
      std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3779
0
          OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3780
0
      if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3781
0
          (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3782
0
           !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3783
0
          !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3784
0
          !Stack->isImplicitTaskFirstprivate(VD))
3785
0
        return;
3786
3787
0
      SourceLocation ELoc = E->getExprLoc();
3788
0
      OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3789
      // The default(none) clause requires that each variable that is referenced
3790
      // in the construct, and does not have a predetermined data-sharing
3791
      // attribute, must have its data-sharing attribute explicitly determined
3792
      // by being listed in a data-sharing attribute clause.
3793
0
      if (DVar.CKind == OMPC_unknown &&
3794
0
          (Stack->getDefaultDSA() == DSA_none ||
3795
0
           Stack->getDefaultDSA() == DSA_private ||
3796
0
           Stack->getDefaultDSA() == DSA_firstprivate) &&
3797
0
          isImplicitOrExplicitTaskingRegion(DKind) &&
3798
0
          VarsWithInheritedDSA.count(VD) == 0) {
3799
0
        bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3800
0
        if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3801
0
                              Stack->getDefaultDSA() == DSA_private)) {
3802
0
          DSAStackTy::DSAVarData DVar =
3803
0
              Stack->getImplicitDSA(VD, /*FromParent=*/false);
3804
0
          InheritedDSA = DVar.CKind == OMPC_unknown;
3805
0
        }
3806
0
        if (InheritedDSA)
3807
0
          VarsWithInheritedDSA[VD] = E;
3808
0
        if (Stack->getDefaultDSA() == DSA_none)
3809
0
          return;
3810
0
      }
3811
3812
      // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3813
      // If implicit-behavior is none, each variable referenced in the
3814
      // construct that does not have a predetermined data-sharing attribute
3815
      // and does not appear in a to or link clause on a declare target
3816
      // directive must be listed in a data-mapping attribute clause, a
3817
      // data-sharing attribute clause (including a data-sharing attribute
3818
      // clause on a combined construct where target. is one of the
3819
      // constituent constructs), or an is_device_ptr clause.
3820
0
      OpenMPDefaultmapClauseKind ClauseKind =
3821
0
          getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3822
0
      if (SemaRef.getLangOpts().OpenMP >= 50) {
3823
0
        bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3824
0
                              OMPC_DEFAULTMAP_MODIFIER_none;
3825
0
        if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3826
0
            VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3827
          // Only check for data-mapping attribute and is_device_ptr here
3828
          // since we have already make sure that the declaration does not
3829
          // have a data-sharing attribute above
3830
0
          if (!Stack->checkMappableExprComponentListsForDecl(
3831
0
                  VD, /*CurrentRegionOnly=*/true,
3832
0
                  [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3833
0
                           MapExprComponents,
3834
0
                       OpenMPClauseKind) {
3835
0
                    auto MI = MapExprComponents.rbegin();
3836
0
                    auto ME = MapExprComponents.rend();
3837
0
                    return MI != ME && MI->getAssociatedDeclaration() == VD;
3838
0
                  })) {
3839
0
            VarsWithInheritedDSA[VD] = E;
3840
0
            return;
3841
0
          }
3842
0
        }
3843
0
      }
3844
0
      if (SemaRef.getLangOpts().OpenMP > 50) {
3845
0
        bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3846
0
                                 OMPC_DEFAULTMAP_MODIFIER_present;
3847
0
        if (IsModifierPresent) {
3848
0
          if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3849
0
                                  OMPC_MAP_MODIFIER_present)) {
3850
0
            ImplicitMapModifier[ClauseKind].push_back(
3851
0
                OMPC_MAP_MODIFIER_present);
3852
0
          }
3853
0
        }
3854
0
      }
3855
3856
0
      if (isOpenMPTargetExecutionDirective(DKind) &&
3857
0
          !Stack->isLoopControlVariable(VD).first) {
3858
0
        if (!Stack->checkMappableExprComponentListsForDecl(
3859
0
                VD, /*CurrentRegionOnly=*/true,
3860
0
                [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3861
0
                           StackComponents,
3862
0
                       OpenMPClauseKind) {
3863
0
                  if (SemaRef.LangOpts.OpenMP >= 50)
3864
0
                    return !StackComponents.empty();
3865
                  // Variable is used if it has been marked as an array, array
3866
                  // section, array shaping or the variable iself.
3867
0
                  return StackComponents.size() == 1 ||
3868
0
                         llvm::all_of(
3869
0
                             llvm::drop_begin(llvm::reverse(StackComponents)),
3870
0
                             [](const OMPClauseMappableExprCommon::
3871
0
                                    MappableComponent &MC) {
3872
0
                               return MC.getAssociatedDeclaration() ==
3873
0
                                          nullptr &&
3874
0
                                      (isa<OMPArraySectionExpr>(
3875
0
                                           MC.getAssociatedExpression()) ||
3876
0
                                       isa<OMPArrayShapingExpr>(
3877
0
                                           MC.getAssociatedExpression()) ||
3878
0
                                       isa<ArraySubscriptExpr>(
3879
0
                                           MC.getAssociatedExpression()));
3880
0
                             });
3881
0
                })) {
3882
0
          bool IsFirstprivate = false;
3883
          // By default lambdas are captured as firstprivates.
3884
0
          if (const auto *RD =
3885
0
                  VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3886
0
            IsFirstprivate = RD->isLambda();
3887
0
          IsFirstprivate =
3888
0
              IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3889
0
          if (IsFirstprivate) {
3890
0
            ImplicitFirstprivate.emplace_back(E);
3891
0
          } else {
3892
0
            OpenMPDefaultmapClauseModifier M =
3893
0
                Stack->getDefaultmapModifier(ClauseKind);
3894
0
            OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3895
0
                M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3896
0
            ImplicitMap[ClauseKind][Kind].emplace_back(E);
3897
0
          }
3898
0
          return;
3899
0
        }
3900
0
      }
3901
3902
      // OpenMP [2.9.3.6, Restrictions, p.2]
3903
      //  A list item that appears in a reduction clause of the innermost
3904
      //  enclosing worksharing or parallel construct may not be accessed in an
3905
      //  explicit task.
3906
0
      DVar = Stack->hasInnermostDSA(
3907
0
          VD,
3908
0
          [](OpenMPClauseKind C, bool AppliedToPointee) {
3909
0
            return C == OMPC_reduction && !AppliedToPointee;
3910
0
          },
3911
0
          [](OpenMPDirectiveKind K) {
3912
0
            return isOpenMPParallelDirective(K) ||
3913
0
                   isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3914
0
          },
3915
0
          /*FromParent=*/true);
3916
0
      if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3917
0
        ErrorFound = true;
3918
0
        SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3919
0
        reportOriginalDsa(SemaRef, Stack, VD, DVar);
3920
0
        return;
3921
0
      }
3922
3923
      // Define implicit data-sharing attributes for task.
3924
0
      DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3925
0
      if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3926
0
           (((Stack->getDefaultDSA() == DSA_firstprivate &&
3927
0
              DVar.CKind == OMPC_firstprivate) ||
3928
0
             (Stack->getDefaultDSA() == DSA_private &&
3929
0
              DVar.CKind == OMPC_private)) &&
3930
0
            !DVar.RefExpr)) &&
3931
0
          !Stack->isLoopControlVariable(VD).first) {
3932
0
        if (Stack->getDefaultDSA() == DSA_private)
3933
0
          ImplicitPrivate.push_back(E);
3934
0
        else
3935
0
          ImplicitFirstprivate.push_back(E);
3936
0
        return;
3937
0
      }
3938
3939
      // Store implicitly used globals with declare target link for parent
3940
      // target.
3941
0
      if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3942
0
          *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3943
0
        Stack->addToParentTargetRegionLinkGlobals(E);
3944
0
        return;
3945
0
      }
3946
0
    }
3947
0
  }
3948
0
  void VisitMemberExpr(MemberExpr *E) {
3949
0
    if (E->isTypeDependent() || E->isValueDependent() ||
3950
0
        E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3951
0
      return;
3952
0
    auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3953
0
    OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3954
0
    if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3955
0
      if (!FD)
3956
0
        return;
3957
0
      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3958
      // Check if the variable has explicit DSA set and stop analysis if it
3959
      // so.
3960
0
      if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3961
0
        return;
3962
3963
0
      if (isOpenMPTargetExecutionDirective(DKind) &&
3964
0
          !Stack->isLoopControlVariable(FD).first &&
3965
0
          !Stack->checkMappableExprComponentListsForDecl(
3966
0
              FD, /*CurrentRegionOnly=*/true,
3967
0
              [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3968
0
                     StackComponents,
3969
0
                 OpenMPClauseKind) {
3970
0
                return isa<CXXThisExpr>(
3971
0
                    cast<MemberExpr>(
3972
0
                        StackComponents.back().getAssociatedExpression())
3973
0
                        ->getBase()
3974
0
                        ->IgnoreParens());
3975
0
              })) {
3976
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3977
        //  A bit-field cannot appear in a map clause.
3978
        //
3979
0
        if (FD->isBitField())
3980
0
          return;
3981
3982
        // Check to see if the member expression is referencing a class that
3983
        // has already been explicitly mapped
3984
0
        if (Stack->isClassPreviouslyMapped(TE->getType()))
3985
0
          return;
3986
3987
0
        OpenMPDefaultmapClauseModifier Modifier =
3988
0
            Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3989
0
        OpenMPDefaultmapClauseKind ClauseKind =
3990
0
            getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3991
0
        OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3992
0
            Modifier, /*IsAggregateOrDeclareTarget*/ true);
3993
0
        ImplicitMap[ClauseKind][Kind].emplace_back(E);
3994
0
        return;
3995
0
      }
3996
3997
0
      SourceLocation ELoc = E->getExprLoc();
3998
      // OpenMP [2.9.3.6, Restrictions, p.2]
3999
      //  A list item that appears in a reduction clause of the innermost
4000
      //  enclosing worksharing or parallel construct may not be accessed in
4001
      //  an  explicit task.
4002
0
      DVar = Stack->hasInnermostDSA(
4003
0
          FD,
4004
0
          [](OpenMPClauseKind C, bool AppliedToPointee) {
4005
0
            return C == OMPC_reduction && !AppliedToPointee;
4006
0
          },
4007
0
          [](OpenMPDirectiveKind K) {
4008
0
            return isOpenMPParallelDirective(K) ||
4009
0
                   isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
4010
0
          },
4011
0
          /*FromParent=*/true);
4012
0
      if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
4013
0
        ErrorFound = true;
4014
0
        SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
4015
0
        reportOriginalDsa(SemaRef, Stack, FD, DVar);
4016
0
        return;
4017
0
      }
4018
4019
      // Define implicit data-sharing attributes for task.
4020
0
      DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
4021
0
      if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
4022
0
          !Stack->isLoopControlVariable(FD).first) {
4023
        // Check if there is a captured expression for the current field in the
4024
        // region. Do not mark it as firstprivate unless there is no captured
4025
        // expression.
4026
        // TODO: try to make it firstprivate.
4027
0
        if (DVar.CKind != OMPC_unknown)
4028
0
          ImplicitFirstprivate.push_back(E);
4029
0
      }
4030
0
      return;
4031
0
    }
4032
0
    if (isOpenMPTargetExecutionDirective(DKind)) {
4033
0
      OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
4034
0
      if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
4035
0
                                        Stack->getCurrentDirective(),
4036
0
                                        /*NoDiagnose=*/true))
4037
0
        return;
4038
0
      const auto *VD = cast<ValueDecl>(
4039
0
          CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4040
0
      if (!Stack->checkMappableExprComponentListsForDecl(
4041
0
              VD, /*CurrentRegionOnly=*/true,
4042
0
              [&CurComponents](
4043
0
                  OMPClauseMappableExprCommon::MappableExprComponentListRef
4044
0
                      StackComponents,
4045
0
                  OpenMPClauseKind) {
4046
0
                auto CCI = CurComponents.rbegin();
4047
0
                auto CCE = CurComponents.rend();
4048
0
                for (const auto &SC : llvm::reverse(StackComponents)) {
4049
                  // Do both expressions have the same kind?
4050
0
                  if (CCI->getAssociatedExpression()->getStmtClass() !=
4051
0
                      SC.getAssociatedExpression()->getStmtClass())
4052
0
                    if (!((isa<OMPArraySectionExpr>(
4053
0
                               SC.getAssociatedExpression()) ||
4054
0
                           isa<OMPArrayShapingExpr>(
4055
0
                               SC.getAssociatedExpression())) &&
4056
0
                          isa<ArraySubscriptExpr>(
4057
0
                              CCI->getAssociatedExpression())))
4058
0
                      return false;
4059
4060
0
                  const Decl *CCD = CCI->getAssociatedDeclaration();
4061
0
                  const Decl *SCD = SC.getAssociatedDeclaration();
4062
0
                  CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4063
0
                  SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4064
0
                  if (SCD != CCD)
4065
0
                    return false;
4066
0
                  std::advance(CCI, 1);
4067
0
                  if (CCI == CCE)
4068
0
                    break;
4069
0
                }
4070
0
                return true;
4071
0
              })) {
4072
0
        Visit(E->getBase());
4073
0
      }
4074
0
    } else if (!TryCaptureCXXThisMembers) {
4075
0
      Visit(E->getBase());
4076
0
    }
4077
0
  }
4078
0
  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
4079
0
    for (OMPClause *C : S->clauses()) {
4080
      // Skip analysis of arguments of private clauses for task|target
4081
      // directives.
4082
0
      if (isa_and_nonnull<OMPPrivateClause>(C))
4083
0
        continue;
4084
      // Skip analysis of arguments of implicitly defined firstprivate clause
4085
      // for task|target directives.
4086
      // Skip analysis of arguments of implicitly defined map clause for target
4087
      // directives.
4088
0
      if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
4089
0
                 C->isImplicit() &&
4090
0
                 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
4091
0
        for (Stmt *CC : C->children()) {
4092
0
          if (CC)
4093
0
            Visit(CC);
4094
0
        }
4095
0
      }
4096
0
    }
4097
    // Check implicitly captured variables.
4098
0
    VisitSubCaptures(S);
4099
0
  }
4100
4101
0
  void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
4102
    // Loop transformation directives do not introduce data sharing
4103
0
    VisitStmt(S);
4104
0
  }
4105
4106
0
  void VisitCallExpr(CallExpr *S) {
4107
0
    for (Stmt *C : S->arguments()) {
4108
0
      if (C) {
4109
        // Check implicitly captured variables in the task-based directives to
4110
        // check if they must be firstprivatized.
4111
0
        Visit(C);
4112
0
      }
4113
0
    }
4114
0
    if (Expr *Callee = S->getCallee()) {
4115
0
      auto *CI = Callee->IgnoreParenImpCasts();
4116
0
      if (auto *CE = dyn_cast<MemberExpr>(CI))
4117
0
        Visit(CE->getBase());
4118
0
      else if (auto *CE = dyn_cast<DeclRefExpr>(CI))
4119
0
        Visit(CE);
4120
0
    }
4121
0
  }
4122
0
  void VisitStmt(Stmt *S) {
4123
0
    for (Stmt *C : S->children()) {
4124
0
      if (C) {
4125
        // Check implicitly captured variables in the task-based directives to
4126
        // check if they must be firstprivatized.
4127
0
        Visit(C);
4128
0
      }
4129
0
    }
4130
0
  }
4131
4132
0
  void visitSubCaptures(CapturedStmt *S) {
4133
0
    for (const CapturedStmt::Capture &Cap : S->captures()) {
4134
0
      if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4135
0
        continue;
4136
0
      VarDecl *VD = Cap.getCapturedVar();
4137
      // Do not try to map the variable if it or its sub-component was mapped
4138
      // already.
4139
0
      if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4140
0
          Stack->checkMappableExprComponentListsForDecl(
4141
0
              VD, /*CurrentRegionOnly=*/true,
4142
0
              [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
4143
0
                 OpenMPClauseKind) { return true; }))
4144
0
        continue;
4145
0
      DeclRefExpr *DRE = buildDeclRefExpr(
4146
0
          SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
4147
0
          Cap.getLocation(), /*RefersToCapture=*/true);
4148
0
      Visit(DRE);
4149
0
    }
4150
0
  }
4151
0
  bool isErrorFound() const { return ErrorFound; }
4152
0
  ArrayRef<Expr *> getImplicitFirstprivate() const {
4153
0
    return ImplicitFirstprivate;
4154
0
  }
4155
0
  ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; }
4156
  ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
4157
0
                                  OpenMPMapClauseKind MK) const {
4158
0
    return ImplicitMap[DK][MK];
4159
0
  }
4160
  ArrayRef<OpenMPMapModifierKind>
4161
0
  getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
4162
0
    return ImplicitMapModifier[Kind];
4163
0
  }
4164
0
  const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
4165
0
    return VarsWithInheritedDSA;
4166
0
  }
4167
4168
  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
4169
0
      : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
4170
    // Process declare target link variables for the target directives.
4171
0
    if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
4172
0
      for (DeclRefExpr *E : Stack->getLinkGlobals())
4173
0
        Visit(E);
4174
0
    }
4175
0
  }
4176
};
4177
} // namespace
4178
4179
static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
4180
                                               OpenMPDirectiveKind DKind,
4181
0
                                               bool ScopeEntry) {
4182
0
  SmallVector<llvm::omp::TraitProperty, 8> Traits;
4183
0
  if (isOpenMPTargetExecutionDirective(DKind))
4184
0
    Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4185
0
  if (isOpenMPTeamsDirective(DKind))
4186
0
    Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4187
0
  if (isOpenMPParallelDirective(DKind))
4188
0
    Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4189
0
  if (isOpenMPWorksharingDirective(DKind))
4190
0
    Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4191
0
  if (isOpenMPSimdDirective(DKind))
4192
0
    Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4193
0
  Stack->handleConstructTrait(Traits, ScopeEntry);
4194
0
}
4195
4196
0
void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
4197
0
  switch (DKind) {
4198
0
  case OMPD_parallel:
4199
0
  case OMPD_parallel_for:
4200
0
  case OMPD_parallel_for_simd:
4201
0
  case OMPD_parallel_sections:
4202
0
  case OMPD_parallel_master:
4203
0
  case OMPD_parallel_masked:
4204
0
  case OMPD_parallel_loop:
4205
0
  case OMPD_teams:
4206
0
  case OMPD_teams_distribute:
4207
0
  case OMPD_teams_distribute_simd: {
4208
0
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4209
0
    QualType KmpInt32PtrTy =
4210
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4211
0
    Sema::CapturedParamNameType Params[] = {
4212
0
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4213
0
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4214
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4215
0
    };
4216
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4217
0
                             Params);
4218
0
    break;
4219
0
  }
4220
0
  case OMPD_target_teams:
4221
0
  case OMPD_target_parallel:
4222
0
  case OMPD_target_parallel_for:
4223
0
  case OMPD_target_parallel_for_simd:
4224
0
  case OMPD_target_parallel_loop:
4225
0
  case OMPD_target_teams_distribute:
4226
0
  case OMPD_target_teams_distribute_simd: {
4227
0
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4228
0
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4229
0
    QualType KmpInt32PtrTy =
4230
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4231
0
    QualType Args[] = {VoidPtrTy};
4232
0
    FunctionProtoType::ExtProtoInfo EPI;
4233
0
    EPI.Variadic = true;
4234
0
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4235
0
    Sema::CapturedParamNameType Params[] = {
4236
0
        std::make_pair(".global_tid.", KmpInt32Ty),
4237
0
        std::make_pair(".part_id.", KmpInt32PtrTy),
4238
0
        std::make_pair(".privates.", VoidPtrTy),
4239
0
        std::make_pair(
4240
0
            ".copy_fn.",
4241
0
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4242
0
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4243
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4244
0
    };
4245
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4246
0
                             Params, /*OpenMPCaptureLevel=*/0);
4247
    // Mark this captured region as inlined, because we don't use outlined
4248
    // function directly.
4249
0
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4250
0
        AlwaysInlineAttr::CreateImplicit(
4251
0
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4252
0
    SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4253
0
    if (getLangOpts().OpenMPIsTargetDevice)
4254
0
      ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4255
0
    ParamsTarget.push_back(
4256
0
        std::make_pair(StringRef(), QualType())); // __context with shared vars;
4257
    // Start a captured region for 'target' with no implicit parameters.
4258
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4259
0
                             ParamsTarget,
4260
0
                             /*OpenMPCaptureLevel=*/1);
4261
0
    Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
4262
0
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4263
0
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4264
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4265
0
    };
4266
    // Start a captured region for 'teams' or 'parallel'.  Both regions have
4267
    // the same implicit parameters.
4268
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4269
0
                             ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4270
0
    break;
4271
0
  }
4272
0
  case OMPD_target:
4273
0
  case OMPD_target_simd: {
4274
0
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4275
0
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4276
0
    QualType KmpInt32PtrTy =
4277
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4278
0
    QualType Args[] = {VoidPtrTy};
4279
0
    FunctionProtoType::ExtProtoInfo EPI;
4280
0
    EPI.Variadic = true;
4281
0
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4282
0
    Sema::CapturedParamNameType Params[] = {
4283
0
        std::make_pair(".global_tid.", KmpInt32Ty),
4284
0
        std::make_pair(".part_id.", KmpInt32PtrTy),
4285
0
        std::make_pair(".privates.", VoidPtrTy),
4286
0
        std::make_pair(
4287
0
            ".copy_fn.",
4288
0
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4289
0
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4290
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4291
0
    };
4292
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4293
0
                             Params, /*OpenMPCaptureLevel=*/0);
4294
    // Mark this captured region as inlined, because we don't use outlined
4295
    // function directly.
4296
0
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4297
0
        AlwaysInlineAttr::CreateImplicit(
4298
0
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4299
0
    SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4300
0
    if (getLangOpts().OpenMPIsTargetDevice)
4301
0
      ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4302
0
    ParamsTarget.push_back(
4303
0
        std::make_pair(StringRef(), QualType())); // __context with shared vars;
4304
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4305
0
                             ParamsTarget,
4306
0
                             /*OpenMPCaptureLevel=*/1);
4307
0
    break;
4308
0
  }
4309
0
  case OMPD_atomic:
4310
0
  case OMPD_critical:
4311
0
  case OMPD_section:
4312
0
  case OMPD_master:
4313
0
  case OMPD_masked:
4314
0
  case OMPD_tile:
4315
0
  case OMPD_unroll:
4316
0
    break;
4317
0
  case OMPD_loop:
4318
    // TODO: 'loop' may require additional parameters depending on the binding.
4319
    // Treat similar to OMPD_simd/OMPD_for for now.
4320
0
  case OMPD_simd:
4321
0
  case OMPD_for:
4322
0
  case OMPD_for_simd:
4323
0
  case OMPD_sections:
4324
0
  case OMPD_single:
4325
0
  case OMPD_taskgroup:
4326
0
  case OMPD_distribute:
4327
0
  case OMPD_distribute_simd:
4328
0
  case OMPD_ordered:
4329
0
  case OMPD_scope:
4330
0
  case OMPD_target_data:
4331
0
  case OMPD_dispatch: {
4332
0
    Sema::CapturedParamNameType Params[] = {
4333
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4334
0
    };
4335
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4336
0
                             Params);
4337
0
    break;
4338
0
  }
4339
0
  case OMPD_task: {
4340
0
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4341
0
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4342
0
    QualType KmpInt32PtrTy =
4343
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4344
0
    QualType Args[] = {VoidPtrTy};
4345
0
    FunctionProtoType::ExtProtoInfo EPI;
4346
0
    EPI.Variadic = true;
4347
0
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4348
0
    Sema::CapturedParamNameType Params[] = {
4349
0
        std::make_pair(".global_tid.", KmpInt32Ty),
4350
0
        std::make_pair(".part_id.", KmpInt32PtrTy),
4351
0
        std::make_pair(".privates.", VoidPtrTy),
4352
0
        std::make_pair(
4353
0
            ".copy_fn.",
4354
0
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4355
0
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4356
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4357
0
    };
4358
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4359
0
                             Params);
4360
    // Mark this captured region as inlined, because we don't use outlined
4361
    // function directly.
4362
0
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4363
0
        AlwaysInlineAttr::CreateImplicit(
4364
0
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4365
0
    break;
4366
0
  }
4367
0
  case OMPD_taskloop:
4368
0
  case OMPD_taskloop_simd:
4369
0
  case OMPD_master_taskloop:
4370
0
  case OMPD_masked_taskloop:
4371
0
  case OMPD_masked_taskloop_simd:
4372
0
  case OMPD_master_taskloop_simd: {
4373
0
    QualType KmpInt32Ty =
4374
0
        Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4375
0
            .withConst();
4376
0
    QualType KmpUInt64Ty =
4377
0
        Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4378
0
            .withConst();
4379
0
    QualType KmpInt64Ty =
4380
0
        Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4381
0
            .withConst();
4382
0
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4383
0
    QualType KmpInt32PtrTy =
4384
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4385
0
    QualType Args[] = {VoidPtrTy};
4386
0
    FunctionProtoType::ExtProtoInfo EPI;
4387
0
    EPI.Variadic = true;
4388
0
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4389
0
    Sema::CapturedParamNameType Params[] = {
4390
0
        std::make_pair(".global_tid.", KmpInt32Ty),
4391
0
        std::make_pair(".part_id.", KmpInt32PtrTy),
4392
0
        std::make_pair(".privates.", VoidPtrTy),
4393
0
        std::make_pair(
4394
0
            ".copy_fn.",
4395
0
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4396
0
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4397
0
        std::make_pair(".lb.", KmpUInt64Ty),
4398
0
        std::make_pair(".ub.", KmpUInt64Ty),
4399
0
        std::make_pair(".st.", KmpInt64Ty),
4400
0
        std::make_pair(".liter.", KmpInt32Ty),
4401
0
        std::make_pair(".reductions.", VoidPtrTy),
4402
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4403
0
    };
4404
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4405
0
                             Params);
4406
    // Mark this captured region as inlined, because we don't use outlined
4407
    // function directly.
4408
0
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4409
0
        AlwaysInlineAttr::CreateImplicit(
4410
0
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4411
0
    break;
4412
0
  }
4413
0
  case OMPD_parallel_masked_taskloop:
4414
0
  case OMPD_parallel_masked_taskloop_simd:
4415
0
  case OMPD_parallel_master_taskloop:
4416
0
  case OMPD_parallel_master_taskloop_simd: {
4417
0
    QualType KmpInt32Ty =
4418
0
        Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4419
0
            .withConst();
4420
0
    QualType KmpUInt64Ty =
4421
0
        Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4422
0
            .withConst();
4423
0
    QualType KmpInt64Ty =
4424
0
        Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4425
0
            .withConst();
4426
0
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4427
0
    QualType KmpInt32PtrTy =
4428
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4429
0
    Sema::CapturedParamNameType ParamsParallel[] = {
4430
0
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4431
0
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4432
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4433
0
    };
4434
    // Start a captured region for 'parallel'.
4435
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4436
0
                             ParamsParallel, /*OpenMPCaptureLevel=*/0);
4437
0
    QualType Args[] = {VoidPtrTy};
4438
0
    FunctionProtoType::ExtProtoInfo EPI;
4439
0
    EPI.Variadic = true;
4440
0
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4441
0
    Sema::CapturedParamNameType Params[] = {
4442
0
        std::make_pair(".global_tid.", KmpInt32Ty),
4443
0
        std::make_pair(".part_id.", KmpInt32PtrTy),
4444
0
        std::make_pair(".privates.", VoidPtrTy),
4445
0
        std::make_pair(
4446
0
            ".copy_fn.",
4447
0
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4448
0
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4449
0
        std::make_pair(".lb.", KmpUInt64Ty),
4450
0
        std::make_pair(".ub.", KmpUInt64Ty),
4451
0
        std::make_pair(".st.", KmpInt64Ty),
4452
0
        std::make_pair(".liter.", KmpInt32Ty),
4453
0
        std::make_pair(".reductions.", VoidPtrTy),
4454
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4455
0
    };
4456
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4457
0
                             Params, /*OpenMPCaptureLevel=*/1);
4458
    // Mark this captured region as inlined, because we don't use outlined
4459
    // function directly.
4460
0
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4461
0
        AlwaysInlineAttr::CreateImplicit(
4462
0
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4463
0
    break;
4464
0
  }
4465
0
  case OMPD_distribute_parallel_for_simd:
4466
0
  case OMPD_distribute_parallel_for: {
4467
0
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4468
0
    QualType KmpInt32PtrTy =
4469
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4470
0
    Sema::CapturedParamNameType Params[] = {
4471
0
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4472
0
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4473
0
        std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4474
0
        std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4475
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4476
0
    };
4477
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4478
0
                             Params);
4479
0
    break;
4480
0
  }
4481
0
  case OMPD_target_teams_loop:
4482
0
  case OMPD_target_teams_distribute_parallel_for:
4483
0
  case OMPD_target_teams_distribute_parallel_for_simd: {
4484
0
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4485
0
    QualType KmpInt32PtrTy =
4486
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4487
0
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4488
4489
0
    QualType Args[] = {VoidPtrTy};
4490
0
    FunctionProtoType::ExtProtoInfo EPI;
4491
0
    EPI.Variadic = true;
4492
0
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4493
0
    Sema::CapturedParamNameType Params[] = {
4494
0
        std::make_pair(".global_tid.", KmpInt32Ty),
4495
0
        std::make_pair(".part_id.", KmpInt32PtrTy),
4496
0
        std::make_pair(".privates.", VoidPtrTy),
4497
0
        std::make_pair(
4498
0
            ".copy_fn.",
4499
0
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4500
0
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4501
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4502
0
    };
4503
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4504
0
                             Params, /*OpenMPCaptureLevel=*/0);
4505
    // Mark this captured region as inlined, because we don't use outlined
4506
    // function directly.
4507
0
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4508
0
        AlwaysInlineAttr::CreateImplicit(
4509
0
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4510
0
    SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4511
0
    if (getLangOpts().OpenMPIsTargetDevice)
4512
0
      ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4513
0
    ParamsTarget.push_back(
4514
0
        std::make_pair(StringRef(), QualType())); // __context with shared vars;
4515
    // Start a captured region for 'target' with no implicit parameters.
4516
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4517
0
                             ParamsTarget, /*OpenMPCaptureLevel=*/1);
4518
4519
0
    Sema::CapturedParamNameType ParamsTeams[] = {
4520
0
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4521
0
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4522
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4523
0
    };
4524
    // Start a captured region for 'target' with no implicit parameters.
4525
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4526
0
                             ParamsTeams, /*OpenMPCaptureLevel=*/2);
4527
4528
0
    Sema::CapturedParamNameType ParamsParallel[] = {
4529
0
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4530
0
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4531
0
        std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4532
0
        std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4533
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4534
0
    };
4535
    // Start a captured region for 'teams' or 'parallel'.  Both regions have
4536
    // the same implicit parameters.
4537
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4538
0
                             ParamsParallel, /*OpenMPCaptureLevel=*/3);
4539
0
    break;
4540
0
  }
4541
4542
0
  case OMPD_teams_loop:
4543
0
  case OMPD_teams_distribute_parallel_for:
4544
0
  case OMPD_teams_distribute_parallel_for_simd: {
4545
0
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4546
0
    QualType KmpInt32PtrTy =
4547
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4548
4549
0
    Sema::CapturedParamNameType ParamsTeams[] = {
4550
0
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4551
0
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4552
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4553
0
    };
4554
    // Start a captured region for 'target' with no implicit parameters.
4555
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4556
0
                             ParamsTeams, /*OpenMPCaptureLevel=*/0);
4557
4558
0
    Sema::CapturedParamNameType ParamsParallel[] = {
4559
0
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4560
0
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4561
0
        std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4562
0
        std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4563
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4564
0
    };
4565
    // Start a captured region for 'teams' or 'parallel'.  Both regions have
4566
    // the same implicit parameters.
4567
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4568
0
                             ParamsParallel, /*OpenMPCaptureLevel=*/1);
4569
0
    break;
4570
0
  }
4571
0
  case OMPD_target_update:
4572
0
  case OMPD_target_enter_data:
4573
0
  case OMPD_target_exit_data: {
4574
0
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4575
0
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4576
0
    QualType KmpInt32PtrTy =
4577
0
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4578
0
    QualType Args[] = {VoidPtrTy};
4579
0
    FunctionProtoType::ExtProtoInfo EPI;
4580
0
    EPI.Variadic = true;
4581
0
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4582
0
    Sema::CapturedParamNameType Params[] = {
4583
0
        std::make_pair(".global_tid.", KmpInt32Ty),
4584
0
        std::make_pair(".part_id.", KmpInt32PtrTy),
4585
0
        std::make_pair(".privates.", VoidPtrTy),
4586
0
        std::make_pair(
4587
0
            ".copy_fn.",
4588
0
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4589
0
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4590
0
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4591
0
    };
4592
0
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4593
0
                             Params);
4594
    // Mark this captured region as inlined, because we don't use outlined
4595
    // function directly.
4596
0
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4597
0
        AlwaysInlineAttr::CreateImplicit(
4598
0
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4599
0
    break;
4600
0
  }
4601
0
  case OMPD_threadprivate:
4602
0
  case OMPD_allocate:
4603
0
  case OMPD_taskyield:
4604
0
  case OMPD_error:
4605
0
  case OMPD_barrier:
4606
0
  case OMPD_taskwait:
4607
0
  case OMPD_cancellation_point:
4608
0
  case OMPD_cancel:
4609
0
  case OMPD_flush:
4610
0
  case OMPD_depobj:
4611
0
  case OMPD_scan:
4612
0
  case OMPD_declare_reduction:
4613
0
  case OMPD_declare_mapper:
4614
0
  case OMPD_declare_simd:
4615
0
  case OMPD_declare_target:
4616
0
  case OMPD_end_declare_target:
4617
0
  case OMPD_requires:
4618
0
  case OMPD_declare_variant:
4619
0
  case OMPD_begin_declare_variant:
4620
0
  case OMPD_end_declare_variant:
4621
0
  case OMPD_metadirective:
4622
0
    llvm_unreachable("OpenMP Directive is not allowed");
4623
0
  case OMPD_unknown:
4624
0
  default:
4625
0
    llvm_unreachable("Unknown OpenMP directive");
4626
0
  }
4627
0
  DSAStack->setContext(CurContext);
4628
0
  handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4629
0
}
4630
4631
0
int Sema::getNumberOfConstructScopes(unsigned Level) const {
4632
0
  return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4633
0
}
4634
4635
0
int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4636
0
  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4637
0
  getOpenMPCaptureRegions(CaptureRegions, DKind);
4638
0
  return CaptureRegions.size();
4639
0
}
4640
4641
static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4642
                                             Expr *CaptureExpr, bool WithInit,
4643
                                             DeclContext *CurContext,
4644
0
                                             bool AsExpression) {
4645
0
  assert(CaptureExpr);
4646
0
  ASTContext &C = S.getASTContext();
4647
0
  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4648
0
  QualType Ty = Init->getType();
4649
0
  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4650
0
    if (S.getLangOpts().CPlusPlus) {
4651
0
      Ty = C.getLValueReferenceType(Ty);
4652
0
    } else {
4653
0
      Ty = C.getPointerType(Ty);
4654
0
      ExprResult Res =
4655
0
          S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4656
0
      if (!Res.isUsable())
4657
0
        return nullptr;
4658
0
      Init = Res.get();
4659
0
    }
4660
0
    WithInit = true;
4661
0
  }
4662
0
  auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
4663
0
                                          CaptureExpr->getBeginLoc());
4664
0
  if (!WithInit)
4665
0
    CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4666
0
  CurContext->addHiddenDecl(CED);
4667
0
  Sema::TentativeAnalysisScope Trap(S);
4668
0
  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4669
0
  return CED;
4670
0
}
4671
4672
static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4673
0
                                 bool WithInit) {
4674
0
  OMPCapturedExprDecl *CD;
4675
0
  if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4676
0
    CD = cast<OMPCapturedExprDecl>(VD);
4677
0
  else
4678
0
    CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4679
0
                          S.CurContext,
4680
0
                          /*AsExpression=*/false);
4681
0
  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4682
0
                          CaptureExpr->getExprLoc());
4683
0
}
4684
4685
static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref,
4686
0
                               StringRef Name) {
4687
0
  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4688
0
  if (!Ref) {
4689
0
    OMPCapturedExprDecl *CD = buildCaptureDecl(
4690
0
        S, &S.getASTContext().Idents.get(Name), CaptureExpr,
4691
0
        /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
4692
0
    Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4693
0
                           CaptureExpr->getExprLoc());
4694
0
  }
4695
0
  ExprResult Res = Ref;
4696
0
  if (!S.getLangOpts().CPlusPlus &&
4697
0
      CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4698
0
      Ref->getType()->isPointerType()) {
4699
0
    Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4700
0
    if (!Res.isUsable())
4701
0
      return ExprError();
4702
0
  }
4703
0
  return S.DefaultLvalueConversion(Res.get());
4704
0
}
4705
4706
namespace {
4707
// OpenMP directives parsed in this section are represented as a
4708
// CapturedStatement with an associated statement.  If a syntax error
4709
// is detected during the parsing of the associated statement, the
4710
// compiler must abort processing and close the CapturedStatement.
4711
//
4712
// Combined directives such as 'target parallel' have more than one
4713
// nested CapturedStatements.  This RAII ensures that we unwind out
4714
// of all the nested CapturedStatements when an error is found.
4715
class CaptureRegionUnwinderRAII {
4716
private:
4717
  Sema &S;
4718
  bool &ErrorFound;
4719
  OpenMPDirectiveKind DKind = OMPD_unknown;
4720
4721
public:
4722
  CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4723
                            OpenMPDirectiveKind DKind)
4724
0
      : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4725
0
  ~CaptureRegionUnwinderRAII() {
4726
0
    if (ErrorFound) {
4727
0
      int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4728
0
      while (--ThisCaptureLevel >= 0)
4729
0
        S.ActOnCapturedRegionError();
4730
0
    }
4731
0
  }
4732
};
4733
} // namespace
4734
4735
0
void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4736
  // Capture variables captured by reference in lambdas for target-based
4737
  // directives.
4738
0
  if (!CurContext->isDependentContext() &&
4739
0
      (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4740
0
       isOpenMPTargetDataManagementDirective(
4741
0
           DSAStack->getCurrentDirective()))) {
4742
0
    QualType Type = V->getType();
4743
0
    if (const auto *RD = Type.getCanonicalType()
4744
0
                             .getNonReferenceType()
4745
0
                             ->getAsCXXRecordDecl()) {
4746
0
      bool SavedForceCaptureByReferenceInTargetExecutable =
4747
0
          DSAStack->isForceCaptureByReferenceInTargetExecutable();
4748
0
      DSAStack->setForceCaptureByReferenceInTargetExecutable(
4749
0
          /*V=*/true);
4750
0
      if (RD->isLambda()) {
4751
0
        llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4752
0
        FieldDecl *ThisCapture;
4753
0
        RD->getCaptureFields(Captures, ThisCapture);
4754
0
        for (const LambdaCapture &LC : RD->captures()) {
4755
0
          if (LC.getCaptureKind() == LCK_ByRef) {
4756
0
            VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4757
0
            DeclContext *VDC = VD->getDeclContext();
4758
0
            if (!VDC->Encloses(CurContext))
4759
0
              continue;
4760
0
            MarkVariableReferenced(LC.getLocation(), VD);
4761
0
          } else if (LC.getCaptureKind() == LCK_This) {
4762
0
            QualType ThisTy = getCurrentThisType();
4763
0
            if (!ThisTy.isNull() &&
4764
0
                Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4765
0
              CheckCXXThisCapture(LC.getLocation());
4766
0
          }
4767
0
        }
4768
0
      }
4769
0
      DSAStack->setForceCaptureByReferenceInTargetExecutable(
4770
0
          SavedForceCaptureByReferenceInTargetExecutable);
4771
0
    }
4772
0
  }
4773
0
}
4774
4775
static bool checkOrderedOrderSpecified(Sema &S,
4776
0
                                       const ArrayRef<OMPClause *> Clauses) {
4777
0
  const OMPOrderedClause *Ordered = nullptr;
4778
0
  const OMPOrderClause *Order = nullptr;
4779
4780
0
  for (const OMPClause *Clause : Clauses) {
4781
0
    if (Clause->getClauseKind() == OMPC_ordered)
4782
0
      Ordered = cast<OMPOrderedClause>(Clause);
4783
0
    else if (Clause->getClauseKind() == OMPC_order) {
4784
0
      Order = cast<OMPOrderClause>(Clause);
4785
0
      if (Order->getKind() != OMPC_ORDER_concurrent)
4786
0
        Order = nullptr;
4787
0
    }
4788
0
    if (Ordered && Order)
4789
0
      break;
4790
0
  }
4791
4792
0
  if (Ordered && Order) {
4793
0
    S.Diag(Order->getKindKwLoc(),
4794
0
           diag::err_omp_simple_clause_incompatible_with_ordered)
4795
0
        << getOpenMPClauseName(OMPC_order)
4796
0
        << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4797
0
        << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4798
0
    S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4799
0
        << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4800
0
    return true;
4801
0
  }
4802
0
  return false;
4803
0
}
4804
4805
StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4806
0
                                      ArrayRef<OMPClause *> Clauses) {
4807
0
  handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4808
0
                                     /* ScopeEntry */ false);
4809
0
  if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4810
0
      DSAStack->getCurrentDirective() == OMPD_critical ||
4811
0
      DSAStack->getCurrentDirective() == OMPD_section ||
4812
0
      DSAStack->getCurrentDirective() == OMPD_master ||
4813
0
      DSAStack->getCurrentDirective() == OMPD_masked)
4814
0
    return S;
4815
4816
0
  bool ErrorFound = false;
4817
0
  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4818
0
      *this, ErrorFound, DSAStack->getCurrentDirective());
4819
0
  if (!S.isUsable()) {
4820
0
    ErrorFound = true;
4821
0
    return StmtError();
4822
0
  }
4823
4824
0
  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4825
0
  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4826
0
  OMPOrderedClause *OC = nullptr;
4827
0
  OMPScheduleClause *SC = nullptr;
4828
0
  SmallVector<const OMPLinearClause *, 4> LCs;
4829
0
  SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4830
  // This is required for proper codegen.
4831
0
  for (OMPClause *Clause : Clauses) {
4832
0
    if (!LangOpts.OpenMPSimd &&
4833
0
        (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) ||
4834
0
         DSAStack->getCurrentDirective() == OMPD_target) &&
4835
0
        Clause->getClauseKind() == OMPC_in_reduction) {
4836
      // Capture taskgroup task_reduction descriptors inside the tasking regions
4837
      // with the corresponding in_reduction items.
4838
0
      auto *IRC = cast<OMPInReductionClause>(Clause);
4839
0
      for (Expr *E : IRC->taskgroup_descriptors())
4840
0
        if (E)
4841
0
          MarkDeclarationsReferencedInExpr(E);
4842
0
    }
4843
0
    if (isOpenMPPrivate(Clause->getClauseKind()) ||
4844
0
        Clause->getClauseKind() == OMPC_copyprivate ||
4845
0
        (getLangOpts().OpenMPUseTLS &&
4846
0
         getASTContext().getTargetInfo().isTLSSupported() &&
4847
0
         Clause->getClauseKind() == OMPC_copyin)) {
4848
0
      DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4849
      // Mark all variables in private list clauses as used in inner region.
4850
0
      for (Stmt *VarRef : Clause->children()) {
4851
0
        if (auto *E = cast_or_null<Expr>(VarRef)) {
4852
0
          MarkDeclarationsReferencedInExpr(E);
4853
0
        }
4854
0
      }
4855
0
      DSAStack->setForceVarCapturing(/*V=*/false);
4856
0
    } else if (isOpenMPLoopTransformationDirective(
4857
0
                   DSAStack->getCurrentDirective())) {
4858
0
      assert(CaptureRegions.empty() &&
4859
0
             "No captured regions in loop transformation directives.");
4860
0
    } else if (CaptureRegions.size() > 1 ||
4861
0
               CaptureRegions.back() != OMPD_unknown) {
4862
0
      if (auto *C = OMPClauseWithPreInit::get(Clause))
4863
0
        PICs.push_back(C);
4864
0
      if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4865
0
        if (Expr *E = C->getPostUpdateExpr())
4866
0
          MarkDeclarationsReferencedInExpr(E);
4867
0
      }
4868
0
    }
4869
0
    if (Clause->getClauseKind() == OMPC_schedule)
4870
0
      SC = cast<OMPScheduleClause>(Clause);
4871
0
    else if (Clause->getClauseKind() == OMPC_ordered)
4872
0
      OC = cast<OMPOrderedClause>(Clause);
4873
0
    else if (Clause->getClauseKind() == OMPC_linear)
4874
0
      LCs.push_back(cast<OMPLinearClause>(Clause));
4875
0
  }
4876
  // Capture allocator expressions if used.
4877
0
  for (Expr *E : DSAStack->getInnerAllocators())
4878
0
    MarkDeclarationsReferencedInExpr(E);
4879
  // OpenMP, 2.7.1 Loop Construct, Restrictions
4880
  // The nonmonotonic modifier cannot be specified if an ordered clause is
4881
  // specified.
4882
0
  if (SC &&
4883
0
      (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4884
0
       SC->getSecondScheduleModifier() ==
4885
0
           OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4886
0
      OC) {
4887
0
    Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4888
0
             ? SC->getFirstScheduleModifierLoc()
4889
0
             : SC->getSecondScheduleModifierLoc(),
4890
0
         diag::err_omp_simple_clause_incompatible_with_ordered)
4891
0
        << getOpenMPClauseName(OMPC_schedule)
4892
0
        << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4893
0
                                         OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4894
0
        << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4895
0
    ErrorFound = true;
4896
0
  }
4897
  // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4898
  // If an order(concurrent) clause is present, an ordered clause may not appear
4899
  // on the same directive.
4900
0
  if (checkOrderedOrderSpecified(*this, Clauses))
4901
0
    ErrorFound = true;
4902
0
  if (!LCs.empty() && OC && OC->getNumForLoops()) {
4903
0
    for (const OMPLinearClause *C : LCs) {
4904
0
      Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4905
0
          << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4906
0
    }
4907
0
    ErrorFound = true;
4908
0
  }
4909
0
  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4910
0
      isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4911
0
      OC->getNumForLoops()) {
4912
0
    Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4913
0
        << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4914
0
    ErrorFound = true;
4915
0
  }
4916
0
  if (ErrorFound) {
4917
0
    return StmtError();
4918
0
  }
4919
0
  StmtResult SR = S;
4920
0
  unsigned CompletedRegions = 0;
4921
0
  for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4922
    // Mark all variables in private list clauses as used in inner region.
4923
    // Required for proper codegen of combined directives.
4924
    // TODO: add processing for other clauses.
4925
0
    if (ThisCaptureRegion != OMPD_unknown) {
4926
0
      for (const clang::OMPClauseWithPreInit *C : PICs) {
4927
0
        OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4928
        // Find the particular capture region for the clause if the
4929
        // directive is a combined one with multiple capture regions.
4930
        // If the directive is not a combined one, the capture region
4931
        // associated with the clause is OMPD_unknown and is generated
4932
        // only once.
4933
0
        if (CaptureRegion == ThisCaptureRegion ||
4934
0
            CaptureRegion == OMPD_unknown) {
4935
0
          if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4936
0
            for (Decl *D : DS->decls())
4937
0
              MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4938
0
          }
4939
0
        }
4940
0
      }
4941
0
    }
4942
0
    if (ThisCaptureRegion == OMPD_target) {
4943
      // Capture allocator traits in the target region. They are used implicitly
4944
      // and, thus, are not captured by default.
4945
0
      for (OMPClause *C : Clauses) {
4946
0
        if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4947
0
          for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4948
0
               ++I) {
4949
0
            OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4950
0
            if (Expr *E = D.AllocatorTraits)
4951
0
              MarkDeclarationsReferencedInExpr(E);
4952
0
          }
4953
0
          continue;
4954
0
        }
4955
0
      }
4956
0
    }
4957
0
    if (ThisCaptureRegion == OMPD_parallel) {
4958
      // Capture temp arrays for inscan reductions and locals in aligned
4959
      // clauses.
4960
0
      for (OMPClause *C : Clauses) {
4961
0
        if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4962
0
          if (RC->getModifier() != OMPC_REDUCTION_inscan)
4963
0
            continue;
4964
0
          for (Expr *E : RC->copy_array_temps())
4965
0
            MarkDeclarationsReferencedInExpr(E);
4966
0
        }
4967
0
        if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4968
0
          for (Expr *E : AC->varlists())
4969
0
            MarkDeclarationsReferencedInExpr(E);
4970
0
        }
4971
0
      }
4972
0
    }
4973
0
    if (++CompletedRegions == CaptureRegions.size())
4974
0
      DSAStack->setBodyComplete();
4975
0
    SR = ActOnCapturedRegionEnd(SR.get());
4976
0
  }
4977
0
  return SR;
4978
0
}
4979
4980
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4981
                              OpenMPDirectiveKind CancelRegion,
4982
0
                              SourceLocation StartLoc) {
4983
  // CancelRegion is only needed for cancel and cancellation_point.
4984
0
  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4985
0
    return false;
4986
4987
0
  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4988
0
      CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4989
0
    return false;
4990
4991
0
  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4992
0
      << getOpenMPDirectiveName(CancelRegion);
4993
0
  return true;
4994
0
}
4995
4996
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4997
                                  OpenMPDirectiveKind CurrentRegion,
4998
                                  const DeclarationNameInfo &CurrentName,
4999
                                  OpenMPDirectiveKind CancelRegion,
5000
                                  OpenMPBindClauseKind BindKind,
5001
0
                                  SourceLocation StartLoc) {
5002
0
  if (Stack->getCurScope()) {
5003
0
    OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
5004
0
    OpenMPDirectiveKind OffendingRegion = ParentRegion;
5005
0
    bool NestingProhibited = false;
5006
0
    bool CloseNesting = true;
5007
0
    bool OrphanSeen = false;
5008
0
    enum {
5009
0
      NoRecommend,
5010
0
      ShouldBeInParallelRegion,
5011
0
      ShouldBeInOrderedRegion,
5012
0
      ShouldBeInTargetRegion,
5013
0
      ShouldBeInTeamsRegion,
5014
0
      ShouldBeInLoopSimdRegion,
5015
0
    } Recommend = NoRecommend;
5016
0
    if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
5017
0
        CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
5018
0
        CurrentRegion != OMPD_parallel &&
5019
0
        !isOpenMPCombinedParallelADirective(CurrentRegion)) {
5020
0
      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
5021
0
          << getOpenMPDirectiveName(CurrentRegion);
5022
0
      return true;
5023
0
    }
5024
0
    if (isOpenMPSimdDirective(ParentRegion) &&
5025
0
        ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
5026
0
         (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
5027
0
          CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
5028
0
          CurrentRegion != OMPD_scan))) {
5029
      // OpenMP [2.16, Nesting of Regions]
5030
      // OpenMP constructs may not be nested inside a simd region.
5031
      // OpenMP [2.8.1,simd Construct, Restrictions]
5032
      // An ordered construct with the simd clause is the only OpenMP
5033
      // construct that can appear in the simd region.
5034
      // Allowing a SIMD construct nested in another SIMD construct is an
5035
      // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
5036
      // message.
5037
      // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
5038
      // The only OpenMP constructs that can be encountered during execution of
5039
      // a simd region are the atomic construct, the loop construct, the simd
5040
      // construct and the ordered construct with the simd clause.
5041
0
      SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
5042
0
                                 ? diag::err_omp_prohibited_region_simd
5043
0
                                 : diag::warn_omp_nesting_simd)
5044
0
          << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
5045
0
      return CurrentRegion != OMPD_simd;
5046
0
    }
5047
0
    if (ParentRegion == OMPD_atomic) {
5048
      // OpenMP [2.16, Nesting of Regions]
5049
      // OpenMP constructs may not be nested inside an atomic region.
5050
0
      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5051
0
      return true;
5052
0
    }
5053
0
    if (CurrentRegion == OMPD_section) {
5054
      // OpenMP [2.7.2, sections Construct, Restrictions]
5055
      // Orphaned section directives are prohibited. That is, the section
5056
      // directives must appear within the sections construct and must not be
5057
      // encountered elsewhere in the sections region.
5058
0
      if (ParentRegion != OMPD_sections &&
5059
0
          ParentRegion != OMPD_parallel_sections) {
5060
0
        SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5061
0
            << (ParentRegion != OMPD_unknown)
5062
0
            << getOpenMPDirectiveName(ParentRegion);
5063
0
        return true;
5064
0
      }
5065
0
      return false;
5066
0
    }
5067
    // Allow some constructs (except teams and cancellation constructs) to be
5068
    // orphaned (they could be used in functions, called from OpenMP regions
5069
    // with the required preconditions).
5070
0
    if (ParentRegion == OMPD_unknown &&
5071
0
        !isOpenMPNestingTeamsDirective(CurrentRegion) &&
5072
0
        CurrentRegion != OMPD_cancellation_point &&
5073
0
        CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5074
0
      return false;
5075
    // Checks needed for mapping "loop" construct. Please check mapLoopConstruct
5076
    // for a detailed explanation
5077
0
    if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
5078
0
        (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
5079
0
        (isOpenMPWorksharingDirective(ParentRegion) ||
5080
0
         ParentRegion == OMPD_loop)) {
5081
0
      int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
5082
0
      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5083
0
          << true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
5084
0
          << getOpenMPDirectiveName(CurrentRegion);
5085
0
      return true;
5086
0
    }
5087
0
    if (CurrentRegion == OMPD_cancellation_point ||
5088
0
        CurrentRegion == OMPD_cancel) {
5089
      // OpenMP [2.16, Nesting of Regions]
5090
      // A cancellation point construct for which construct-type-clause is
5091
      // taskgroup must be nested inside a task construct. A cancellation
5092
      // point construct for which construct-type-clause is not taskgroup must
5093
      // be closely nested inside an OpenMP construct that matches the type
5094
      // specified in construct-type-clause.
5095
      // A cancel construct for which construct-type-clause is taskgroup must be
5096
      // nested inside a task construct. A cancel construct for which
5097
      // construct-type-clause is not taskgroup must be closely nested inside an
5098
      // OpenMP construct that matches the type specified in
5099
      // construct-type-clause.
5100
0
      NestingProhibited =
5101
0
          !((CancelRegion == OMPD_parallel &&
5102
0
             (ParentRegion == OMPD_parallel ||
5103
0
              ParentRegion == OMPD_target_parallel)) ||
5104
0
            (CancelRegion == OMPD_for &&
5105
0
             (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5106
0
              ParentRegion == OMPD_target_parallel_for ||
5107
0
              ParentRegion == OMPD_distribute_parallel_for ||
5108
0
              ParentRegion == OMPD_teams_distribute_parallel_for ||
5109
0
              ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5110
0
            (CancelRegion == OMPD_taskgroup &&
5111
0
             (ParentRegion == OMPD_task ||
5112
0
              (SemaRef.getLangOpts().OpenMP >= 50 &&
5113
0
               (ParentRegion == OMPD_taskloop ||
5114
0
                ParentRegion == OMPD_master_taskloop ||
5115
0
                ParentRegion == OMPD_masked_taskloop ||
5116
0
                ParentRegion == OMPD_parallel_masked_taskloop ||
5117
0
                ParentRegion == OMPD_parallel_master_taskloop)))) ||
5118
0
            (CancelRegion == OMPD_sections &&
5119
0
             (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5120
0
              ParentRegion == OMPD_parallel_sections)));
5121
0
      OrphanSeen = ParentRegion == OMPD_unknown;
5122
0
    } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5123
      // OpenMP 5.1 [2.22, Nesting of Regions]
5124
      // A masked region may not be closely nested inside a worksharing, loop,
5125
      // atomic, task, or taskloop region.
5126
0
      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
5127
0
                          isOpenMPGenericLoopDirective(ParentRegion) ||
5128
0
                          isOpenMPTaskingDirective(ParentRegion);
5129
0
    } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
5130
      // OpenMP [2.16, Nesting of Regions]
5131
      // A critical region may not be nested (closely or otherwise) inside a
5132
      // critical region with the same name. Note that this restriction is not
5133
      // sufficient to prevent deadlock.
5134
0
      SourceLocation PreviousCriticalLoc;
5135
0
      bool DeadLock = Stack->hasDirective(
5136
0
          [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
5137
0
                                              const DeclarationNameInfo &DNI,
5138
0
                                              SourceLocation Loc) {
5139
0
            if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
5140
0
              PreviousCriticalLoc = Loc;
5141
0
              return true;
5142
0
            }
5143
0
            return false;
5144
0
          },
5145
0
          false /* skip top directive */);
5146
0
      if (DeadLock) {
5147
0
        SemaRef.Diag(StartLoc,
5148
0
                     diag::err_omp_prohibited_region_critical_same_name)
5149
0
            << CurrentName.getName();
5150
0
        if (PreviousCriticalLoc.isValid())
5151
0
          SemaRef.Diag(PreviousCriticalLoc,
5152
0
                       diag::note_omp_previous_critical_region);
5153
0
        return true;
5154
0
      }
5155
0
    } else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
5156
      // OpenMP 5.1 [2.22, Nesting of Regions]
5157
      // A scope region may not be closely nested inside a worksharing, loop,
5158
      // task, taskloop, critical, ordered, atomic, or masked region.
5159
      // OpenMP 5.1 [2.22, Nesting of Regions]
5160
      // A barrier region may not be closely nested inside a worksharing, loop,
5161
      // task, taskloop, critical, ordered, atomic, or masked region.
5162
0
      NestingProhibited =
5163
0
          isOpenMPWorksharingDirective(ParentRegion) ||
5164
0
          isOpenMPGenericLoopDirective(ParentRegion) ||
5165
0
          isOpenMPTaskingDirective(ParentRegion) ||
5166
0
          ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5167
0
          ParentRegion == OMPD_parallel_master ||
5168
0
          ParentRegion == OMPD_parallel_masked ||
5169
0
          ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5170
0
    } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
5171
0
               !isOpenMPParallelDirective(CurrentRegion) &&
5172
0
               !isOpenMPTeamsDirective(CurrentRegion)) {
5173
      // OpenMP 5.1 [2.22, Nesting of Regions]
5174
      // A loop region that binds to a parallel region or a worksharing region
5175
      // may not be closely nested inside a worksharing, loop, task, taskloop,
5176
      // critical, ordered, atomic, or masked region.
5177
0
      NestingProhibited =
5178
0
          isOpenMPWorksharingDirective(ParentRegion) ||
5179
0
          isOpenMPGenericLoopDirective(ParentRegion) ||
5180
0
          isOpenMPTaskingDirective(ParentRegion) ||
5181
0
          ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5182
0
          ParentRegion == OMPD_parallel_master ||
5183
0
          ParentRegion == OMPD_parallel_masked ||
5184
0
          ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5185
0
      Recommend = ShouldBeInParallelRegion;
5186
0
    } else if (CurrentRegion == OMPD_ordered) {
5187
      // OpenMP [2.16, Nesting of Regions]
5188
      // An ordered region may not be closely nested inside a critical,
5189
      // atomic, or explicit task region.
5190
      // An ordered region must be closely nested inside a loop region (or
5191
      // parallel loop region) with an ordered clause.
5192
      // OpenMP [2.8.1,simd Construct, Restrictions]
5193
      // An ordered construct with the simd clause is the only OpenMP construct
5194
      // that can appear in the simd region.
5195
0
      NestingProhibited = ParentRegion == OMPD_critical ||
5196
0
                          isOpenMPTaskingDirective(ParentRegion) ||
5197
0
                          !(isOpenMPSimdDirective(ParentRegion) ||
5198
0
                            Stack->isParentOrderedRegion());
5199
0
      Recommend = ShouldBeInOrderedRegion;
5200
0
    } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
5201
      // OpenMP [2.16, Nesting of Regions]
5202
      // If specified, a teams construct must be contained within a target
5203
      // construct.
5204
0
      NestingProhibited =
5205
0
          (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5206
0
          (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5207
0
           ParentRegion != OMPD_target);
5208
0
      OrphanSeen = ParentRegion == OMPD_unknown;
5209
0
      Recommend = ShouldBeInTargetRegion;
5210
0
    } else if (CurrentRegion == OMPD_scan) {
5211
      // OpenMP [2.16, Nesting of Regions]
5212
      // If specified, a teams construct must be contained within a target
5213
      // construct.
5214
0
      NestingProhibited =
5215
0
          SemaRef.LangOpts.OpenMP < 50 ||
5216
0
          (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5217
0
           ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5218
0
           ParentRegion != OMPD_parallel_for_simd);
5219
0
      OrphanSeen = ParentRegion == OMPD_unknown;
5220
0
      Recommend = ShouldBeInLoopSimdRegion;
5221
0
    }
5222
0
    if (!NestingProhibited &&
5223
0
        !isOpenMPTargetExecutionDirective(CurrentRegion) &&
5224
0
        !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
5225
0
        (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5226
      // OpenMP [5.1, 2.22, Nesting of Regions]
5227
      // distribute, distribute simd, distribute parallel worksharing-loop,
5228
      // distribute parallel worksharing-loop SIMD, loop, parallel regions,
5229
      // including any parallel regions arising from combined constructs,
5230
      // omp_get_num_teams() regions, and omp_get_team_num() regions are the
5231
      // only OpenMP regions that may be strictly nested inside the teams
5232
      // region.
5233
      //
5234
      // As an extension, we permit atomic within teams as well.
5235
0
      NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
5236
0
                          !isOpenMPDistributeDirective(CurrentRegion) &&
5237
0
                          CurrentRegion != OMPD_loop &&
5238
0
                          !(SemaRef.getLangOpts().OpenMPExtensions &&
5239
0
                            CurrentRegion == OMPD_atomic);
5240
0
      Recommend = ShouldBeInParallelRegion;
5241
0
    }
5242
0
    if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5243
      // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5244
      // If the bind clause is present on the loop construct and binding is
5245
      // teams then the corresponding loop region must be strictly nested inside
5246
      // a teams region.
5247
0
      NestingProhibited = BindKind == OMPC_BIND_teams &&
5248
0
                          ParentRegion != OMPD_teams &&
5249
0
                          ParentRegion != OMPD_target_teams;
5250
0
      Recommend = ShouldBeInTeamsRegion;
5251
0
    }
5252
0
    if (!NestingProhibited &&
5253
0
        isOpenMPNestingDistributeDirective(CurrentRegion)) {
5254
      // OpenMP 4.5 [2.17 Nesting of Regions]
5255
      // The region associated with the distribute construct must be strictly
5256
      // nested inside a teams region
5257
0
      NestingProhibited =
5258
0
          (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5259
0
      Recommend = ShouldBeInTeamsRegion;
5260
0
    }
5261
0
    if (!NestingProhibited &&
5262
0
        (isOpenMPTargetExecutionDirective(CurrentRegion) ||
5263
0
         isOpenMPTargetDataManagementDirective(CurrentRegion))) {
5264
      // OpenMP 4.5 [2.17 Nesting of Regions]
5265
      // If a target, target update, target data, target enter data, or
5266
      // target exit data construct is encountered during execution of a
5267
      // target region, the behavior is unspecified.
5268
0
      NestingProhibited = Stack->hasDirective(
5269
0
          [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
5270
0
                             SourceLocation) {
5271
0
            if (isOpenMPTargetExecutionDirective(K)) {
5272
0
              OffendingRegion = K;
5273
0
              return true;
5274
0
            }
5275
0
            return false;
5276
0
          },
5277
0
          false /* don't skip top directive */);
5278
0
      CloseNesting = false;
5279
0
    }
5280
0
    if (NestingProhibited) {
5281
0
      if (OrphanSeen) {
5282
0
        SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5283
0
            << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5284
0
      } else {
5285
0
        SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5286
0
            << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5287
0
            << Recommend << getOpenMPDirectiveName(CurrentRegion);
5288
0
      }
5289
0
      return true;
5290
0
    }
5291
0
  }
5292
0
  return false;
5293
0
}
5294
5295
struct Kind2Unsigned {
5296
  using argument_type = OpenMPDirectiveKind;
5297
0
  unsigned operator()(argument_type DK) { return unsigned(DK); }
5298
};
5299
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
5300
                           ArrayRef<OMPClause *> Clauses,
5301
0
                           ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5302
0
  bool ErrorFound = false;
5303
0
  unsigned NamedModifiersNumber = 0;
5304
0
  llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5305
0
  FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5306
0
  SmallVector<SourceLocation, 4> NameModifierLoc;
5307
0
  for (const OMPClause *C : Clauses) {
5308
0
    if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5309
      // At most one if clause without a directive-name-modifier can appear on
5310
      // the directive.
5311
0
      OpenMPDirectiveKind CurNM = IC->getNameModifier();
5312
0
      if (FoundNameModifiers[CurNM]) {
5313
0
        S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5314
0
            << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5315
0
            << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5316
0
        ErrorFound = true;
5317
0
      } else if (CurNM != OMPD_unknown) {
5318
0
        NameModifierLoc.push_back(IC->getNameModifierLoc());
5319
0
        ++NamedModifiersNumber;
5320
0
      }
5321
0
      FoundNameModifiers[CurNM] = IC;
5322
0
      if (CurNM == OMPD_unknown)
5323
0
        continue;
5324
      // Check if the specified name modifier is allowed for the current
5325
      // directive.
5326
      // At most one if clause with the particular directive-name-modifier can
5327
      // appear on the directive.
5328
0
      if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5329
0
        S.Diag(IC->getNameModifierLoc(),
5330
0
               diag::err_omp_wrong_if_directive_name_modifier)
5331
0
            << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5332
0
        ErrorFound = true;
5333
0
      }
5334
0
    }
5335
0
  }
5336
  // If any if clause on the directive includes a directive-name-modifier then
5337
  // all if clauses on the directive must include a directive-name-modifier.
5338
0
  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5339
0
    if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5340
0
      S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5341
0
             diag::err_omp_no_more_if_clause);
5342
0
    } else {
5343
0
      std::string Values;
5344
0
      std::string Sep(", ");
5345
0
      unsigned AllowedCnt = 0;
5346
0
      unsigned TotalAllowedNum =
5347
0
          AllowedNameModifiers.size() - NamedModifiersNumber;
5348
0
      for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5349
0
           ++Cnt) {
5350
0
        OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5351
0
        if (!FoundNameModifiers[NM]) {
5352
0
          Values += "'";
5353
0
          Values += getOpenMPDirectiveName(NM);
5354
0
          Values += "'";
5355
0
          if (AllowedCnt + 2 == TotalAllowedNum)
5356
0
            Values += " or ";
5357
0
          else if (AllowedCnt + 1 != TotalAllowedNum)
5358
0
            Values += Sep;
5359
0
          ++AllowedCnt;
5360
0
        }
5361
0
      }
5362
0
      S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5363
0
             diag::err_omp_unnamed_if_clause)
5364
0
          << (TotalAllowedNum > 1) << Values;
5365
0
    }
5366
0
    for (SourceLocation Loc : NameModifierLoc) {
5367
0
      S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5368
0
    }
5369
0
    ErrorFound = true;
5370
0
  }
5371
0
  return ErrorFound;
5372
0
}
5373
5374
static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5375
                                                   SourceLocation &ELoc,
5376
                                                   SourceRange &ERange,
5377
                                                   bool AllowArraySection,
5378
0
                                                   StringRef DiagType) {
5379
0
  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5380
0
      RefExpr->containsUnexpandedParameterPack())
5381
0
    return std::make_pair(nullptr, true);
5382
5383
  // OpenMP [3.1, C/C++]
5384
  //  A list item is a variable name.
5385
  // OpenMP  [2.9.3.3, Restrictions, p.1]
5386
  //  A variable that is part of another variable (as an array or
5387
  //  structure element) cannot appear in a private clause.
5388
0
  RefExpr = RefExpr->IgnoreParens();
5389
0
  enum {
5390
0
    NoArrayExpr = -1,
5391
0
    ArraySubscript = 0,
5392
0
    OMPArraySection = 1
5393
0
  } IsArrayExpr = NoArrayExpr;
5394
0
  if (AllowArraySection) {
5395
0
    if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5396
0
      Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5397
0
      while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5398
0
        Base = TempASE->getBase()->IgnoreParenImpCasts();
5399
0
      RefExpr = Base;
5400
0
      IsArrayExpr = ArraySubscript;
5401
0
    } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5402
0
      Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5403
0
      while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5404
0
        Base = TempOASE->getBase()->IgnoreParenImpCasts();
5405
0
      while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5406
0
        Base = TempASE->getBase()->IgnoreParenImpCasts();
5407
0
      RefExpr = Base;
5408
0
      IsArrayExpr = OMPArraySection;
5409
0
    }
5410
0
  }
5411
0
  ELoc = RefExpr->getExprLoc();
5412
0
  ERange = RefExpr->getSourceRange();
5413
0
  RefExpr = RefExpr->IgnoreParenImpCasts();
5414
0
  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5415
0
  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5416
0
  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5417
0
      (S.getCurrentThisType().isNull() || !ME ||
5418
0
       !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5419
0
       !isa<FieldDecl>(ME->getMemberDecl()))) {
5420
0
    if (IsArrayExpr != NoArrayExpr) {
5421
0
      S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5422
0
          << IsArrayExpr << ERange;
5423
0
    } else if (!DiagType.empty()) {
5424
0
      unsigned DiagSelect = S.getLangOpts().CPlusPlus
5425
0
                                ? (S.getCurrentThisType().isNull() ? 1 : 2)
5426
0
                                : 0;
5427
0
      S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5428
0
          << DiagSelect << DiagType << ERange;
5429
0
    } else {
5430
0
      S.Diag(ELoc,
5431
0
             AllowArraySection
5432
0
                 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5433
0
                 : diag::err_omp_expected_var_name_member_expr)
5434
0
          << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5435
0
    }
5436
0
    return std::make_pair(nullptr, false);
5437
0
  }
5438
0
  return std::make_pair(
5439
0
      getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5440
0
}
5441
5442
namespace {
5443
/// Checks if the allocator is used in uses_allocators clause to be allowed in
5444
/// target regions.
5445
class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5446
  DSAStackTy *S = nullptr;
5447
5448
public:
5449
0
  bool VisitDeclRefExpr(const DeclRefExpr *E) {
5450
0
    return S->isUsesAllocatorsDecl(E->getDecl())
5451
0
               .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5452
0
           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5453
0
  }
5454
0
  bool VisitStmt(const Stmt *S) {
5455
0
    for (const Stmt *Child : S->children()) {
5456
0
      if (Child && Visit(Child))
5457
0
        return true;
5458
0
    }
5459
0
    return false;
5460
0
  }
5461
0
  explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5462
};
5463
} // namespace
5464
5465
static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5466
0
                                 ArrayRef<OMPClause *> Clauses) {
5467
0
  assert(!S.CurContext->isDependentContext() &&
5468
0
         "Expected non-dependent context.");
5469
0
  auto AllocateRange =
5470
0
      llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5471
0
  llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5472
0
  auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5473
0
    return isOpenMPPrivate(C->getClauseKind());
5474
0
  });
5475
0
  for (OMPClause *Cl : PrivateRange) {
5476
0
    MutableArrayRef<Expr *>::iterator I, It, Et;
5477
0
    if (Cl->getClauseKind() == OMPC_private) {
5478
0
      auto *PC = cast<OMPPrivateClause>(Cl);
5479
0
      I = PC->private_copies().begin();
5480
0
      It = PC->varlist_begin();
5481
0
      Et = PC->varlist_end();
5482
0
    } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5483
0
      auto *PC = cast<OMPFirstprivateClause>(Cl);
5484
0
      I = PC->private_copies().begin();
5485
0
      It = PC->varlist_begin();
5486
0
      Et = PC->varlist_end();
5487
0
    } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5488
0
      auto *PC = cast<OMPLastprivateClause>(Cl);
5489
0
      I = PC->private_copies().begin();
5490
0
      It = PC->varlist_begin();
5491
0
      Et = PC->varlist_end();
5492
0
    } else if (Cl->getClauseKind() == OMPC_linear) {
5493
0
      auto *PC = cast<OMPLinearClause>(Cl);
5494
0
      I = PC->privates().begin();
5495
0
      It = PC->varlist_begin();
5496
0
      Et = PC->varlist_end();
5497
0
    } else if (Cl->getClauseKind() == OMPC_reduction) {
5498
0
      auto *PC = cast<OMPReductionClause>(Cl);
5499
0
      I = PC->privates().begin();
5500
0
      It = PC->varlist_begin();
5501
0
      Et = PC->varlist_end();
5502
0
    } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5503
0
      auto *PC = cast<OMPTaskReductionClause>(Cl);
5504
0
      I = PC->privates().begin();
5505
0
      It = PC->varlist_begin();
5506
0
      Et = PC->varlist_end();
5507
0
    } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5508
0
      auto *PC = cast<OMPInReductionClause>(Cl);
5509
0
      I = PC->privates().begin();
5510
0
      It = PC->varlist_begin();
5511
0
      Et = PC->varlist_end();
5512
0
    } else {
5513
0
      llvm_unreachable("Expected private clause.");
5514
0
    }
5515
0
    for (Expr *E : llvm::make_range(It, Et)) {
5516
0
      if (!*I) {
5517
0
        ++I;
5518
0
        continue;
5519
0
      }
5520
0
      SourceLocation ELoc;
5521
0
      SourceRange ERange;
5522
0
      Expr *SimpleRefExpr = E;
5523
0
      auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5524
0
                                /*AllowArraySection=*/true);
5525
0
      DeclToCopy.try_emplace(Res.first,
5526
0
                             cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5527
0
      ++I;
5528
0
    }
5529
0
  }
5530
0
  for (OMPClause *C : AllocateRange) {
5531
0
    auto *AC = cast<OMPAllocateClause>(C);
5532
0
    if (S.getLangOpts().OpenMP >= 50 &&
5533
0
        !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5534
0
        isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5535
0
        AC->getAllocator()) {
5536
0
      Expr *Allocator = AC->getAllocator();
5537
      // OpenMP, 2.12.5 target Construct
5538
      // Memory allocators that do not appear in a uses_allocators clause cannot
5539
      // appear as an allocator in an allocate clause or be used in the target
5540
      // region unless a requires directive with the dynamic_allocators clause
5541
      // is present in the same compilation unit.
5542
0
      AllocatorChecker Checker(Stack);
5543
0
      if (Checker.Visit(Allocator))
5544
0
        S.Diag(Allocator->getExprLoc(),
5545
0
               diag::err_omp_allocator_not_in_uses_allocators)
5546
0
            << Allocator->getSourceRange();
5547
0
    }
5548
0
    OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5549
0
        getAllocatorKind(S, Stack, AC->getAllocator());
5550
    // OpenMP, 2.11.4 allocate Clause, Restrictions.
5551
    // For task, taskloop or target directives, allocation requests to memory
5552
    // allocators with the trait access set to thread result in unspecified
5553
    // behavior.
5554
0
    if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5555
0
        (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5556
0
         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5557
0
      S.Diag(AC->getAllocator()->getExprLoc(),
5558
0
             diag::warn_omp_allocate_thread_on_task_target_directive)
5559
0
          << getOpenMPDirectiveName(Stack->getCurrentDirective());
5560
0
    }
5561
0
    for (Expr *E : AC->varlists()) {
5562
0
      SourceLocation ELoc;
5563
0
      SourceRange ERange;
5564
0
      Expr *SimpleRefExpr = E;
5565
0
      auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5566
0
      ValueDecl *VD = Res.first;
5567
0
      DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5568
0
      if (!isOpenMPPrivate(Data.CKind)) {
5569
0
        S.Diag(E->getExprLoc(),
5570
0
               diag::err_omp_expected_private_copy_for_allocate);
5571
0
        continue;
5572
0
      }
5573
0
      VarDecl *PrivateVD = DeclToCopy[VD];
5574
0
      if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5575
0
                                            AllocatorKind, AC->getAllocator()))
5576
0
        continue;
5577
      // Placeholder until allocate clause supports align modifier.
5578
0
      Expr *Alignment = nullptr;
5579
0
      applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5580
0
                                Alignment, E->getSourceRange());
5581
0
    }
5582
0
  }
5583
0
}
5584
5585
namespace {
5586
/// Rewrite statements and expressions for Sema \p Actions CurContext.
5587
///
5588
/// Used to wrap already parsed statements/expressions into a new CapturedStmt
5589
/// context. DeclRefExpr used inside the new context are changed to refer to the
5590
/// captured variable instead.
5591
class CaptureVars : public TreeTransform<CaptureVars> {
5592
  using BaseTransform = TreeTransform<CaptureVars>;
5593
5594
public:
5595
0
  CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5596
5597
0
  bool AlwaysRebuild() { return true; }
5598
};
5599
} // namespace
5600
5601
static VarDecl *precomputeExpr(Sema &Actions,
5602
                               SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5603
0
                               StringRef Name) {
5604
0
  Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5605
0
  VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5606
0
                                 dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5607
0
  auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5608
0
      Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5609
0
  Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5610
0
  BodyStmts.push_back(NewDeclStmt);
5611
0
  return NewVar;
5612
0
}
5613
5614
/// Create a closure that computes the number of iterations of a loop.
5615
///
5616
/// \param Actions   The Sema object.
5617
/// \param LogicalTy Type for the logical iteration number.
5618
/// \param Rel       Comparison operator of the loop condition.
5619
/// \param StartExpr Value of the loop counter at the first iteration.
5620
/// \param StopExpr  Expression the loop counter is compared against in the loop
5621
/// condition. \param StepExpr      Amount of increment after each iteration.
5622
///
5623
/// \return Closure (CapturedStmt) of the distance calculation.
5624
static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5625
                                       BinaryOperator::Opcode Rel,
5626
                                       Expr *StartExpr, Expr *StopExpr,
5627
0
                                       Expr *StepExpr) {
5628
0
  ASTContext &Ctx = Actions.getASTContext();
5629
0
  TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5630
5631
  // Captured regions currently don't support return values, we use an
5632
  // out-parameter instead. All inputs are implicit captures.
5633
  // TODO: Instead of capturing each DeclRefExpr occurring in
5634
  // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5635
0
  QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5636
0
  Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5637
0
                                          {StringRef(), QualType()}};
5638
0
  Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5639
5640
0
  Stmt *Body;
5641
0
  {
5642
0
    Sema::CompoundScopeRAII CompoundScope(Actions);
5643
0
    CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5644
5645
    // Get the LValue expression for the result.
5646
0
    ImplicitParamDecl *DistParam = CS->getParam(0);
5647
0
    DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5648
0
        DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5649
5650
0
    SmallVector<Stmt *, 4> BodyStmts;
5651
5652
    // Capture all referenced variable references.
5653
    // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5654
    // CapturedStmt, we could compute them before and capture the result, to be
5655
    // used jointly with the LoopVar function.
5656
0
    VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5657
0
    VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5658
0
    VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5659
0
    auto BuildVarRef = [&](VarDecl *VD) {
5660
0
      return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5661
0
    };
5662
5663
0
    IntegerLiteral *Zero = IntegerLiteral::Create(
5664
0
        Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5665
0
    IntegerLiteral *One = IntegerLiteral::Create(
5666
0
        Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5667
0
    Expr *Dist;
5668
0
    if (Rel == BO_NE) {
5669
      // When using a != comparison, the increment can be +1 or -1. This can be
5670
      // dynamic at runtime, so we need to check for the direction.
5671
0
      Expr *IsNegStep = AssertSuccess(
5672
0
          Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5673
5674
      // Positive increment.
5675
0
      Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5676
0
          nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5677
0
      ForwardRange = AssertSuccess(
5678
0
          Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5679
0
      Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5680
0
          nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5681
5682
      // Negative increment.
5683
0
      Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5684
0
          nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5685
0
      BackwardRange = AssertSuccess(
5686
0
          Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5687
0
      Expr *NegIncAmount = AssertSuccess(
5688
0
          Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5689
0
      Expr *BackwardDist = AssertSuccess(
5690
0
          Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5691
5692
      // Use the appropriate case.
5693
0
      Dist = AssertSuccess(Actions.ActOnConditionalOp(
5694
0
          {}, {}, IsNegStep, BackwardDist, ForwardDist));
5695
0
    } else {
5696
0
      assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5697
0
             "Expected one of these relational operators");
5698
5699
      // We can derive the direction from any other comparison operator. It is
5700
      // non well-formed OpenMP if Step increments/decrements in the other
5701
      // directions. Whether at least the first iteration passes the loop
5702
      // condition.
5703
0
      Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5704
0
          nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5705
5706
      // Compute the range between first and last counter value.
5707
0
      Expr *Range;
5708
0
      if (Rel == BO_GE || Rel == BO_GT)
5709
0
        Range = AssertSuccess(Actions.BuildBinOp(
5710
0
            nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5711
0
      else
5712
0
        Range = AssertSuccess(Actions.BuildBinOp(
5713
0
            nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5714
5715
      // Ensure unsigned range space.
5716
0
      Range =
5717
0
          AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5718
5719
0
      if (Rel == BO_LE || Rel == BO_GE) {
5720
        // Add one to the range if the relational operator is inclusive.
5721
0
        Range =
5722
0
            AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5723
0
      }
5724
5725
      // Divide by the absolute step amount. If the range is not a multiple of
5726
      // the step size, rounding-up the effective upper bound ensures that the
5727
      // last iteration is included.
5728
      // Note that the rounding-up may cause an overflow in a temporry that
5729
      // could be avoided, but would have occurred in a C-style for-loop as
5730
      // well.
5731
0
      Expr *Divisor = BuildVarRef(NewStep);
5732
0
      if (Rel == BO_GE || Rel == BO_GT)
5733
0
        Divisor =
5734
0
            AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5735
0
      Expr *DivisorMinusOne =
5736
0
          AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5737
0
      Expr *RangeRoundUp = AssertSuccess(
5738
0
          Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5739
0
      Dist = AssertSuccess(
5740
0
          Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5741
5742
      // If there is not at least one iteration, the range contains garbage. Fix
5743
      // to zero in this case.
5744
0
      Dist = AssertSuccess(
5745
0
          Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5746
0
    }
5747
5748
    // Assign the result to the out-parameter.
5749
0
    Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5750
0
        Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5751
0
    BodyStmts.push_back(ResultAssign);
5752
5753
0
    Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5754
0
  }
5755
5756
0
  return cast<CapturedStmt>(
5757
0
      AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5758
0
}
5759
5760
/// Create a closure that computes the loop variable from the logical iteration
5761
/// number.
5762
///
5763
/// \param Actions   The Sema object.
5764
/// \param LoopVarTy Type for the loop variable used for result value.
5765
/// \param LogicalTy Type for the logical iteration number.
5766
/// \param StartExpr Value of the loop counter at the first iteration.
5767
/// \param Step      Amount of increment after each iteration.
5768
/// \param Deref     Whether the loop variable is a dereference of the loop
5769
/// counter variable.
5770
///
5771
/// \return Closure (CapturedStmt) of the loop value calculation.
5772
static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5773
                                      QualType LogicalTy,
5774
                                      DeclRefExpr *StartExpr, Expr *Step,
5775
0
                                      bool Deref) {
5776
0
  ASTContext &Ctx = Actions.getASTContext();
5777
5778
  // Pass the result as an out-parameter. Passing as return value would require
5779
  // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5780
  // invoke a copy constructor.
5781
0
  QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5782
0
  Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5783
0
                                          {"Logical", LogicalTy},
5784
0
                                          {StringRef(), QualType()}};
5785
0
  Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5786
5787
  // Capture the initial iterator which represents the LoopVar value at the
5788
  // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5789
  // it in every iteration, capture it by value before it is modified.
5790
0
  VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5791
0
  bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5792
0
                                            Sema::TryCapture_ExplicitByVal, {});
5793
0
  (void)Invalid;
5794
0
  assert(!Invalid && "Expecting capture-by-value to work.");
5795
5796
0
  Expr *Body;
5797
0
  {
5798
0
    Sema::CompoundScopeRAII CompoundScope(Actions);
5799
0
    auto *CS = cast<CapturedDecl>(Actions.CurContext);
5800
5801
0
    ImplicitParamDecl *TargetParam = CS->getParam(0);
5802
0
    DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5803
0
        TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5804
0
    ImplicitParamDecl *IndvarParam = CS->getParam(1);
5805
0
    DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5806
0
        IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5807
5808
    // Capture the Start expression.
5809
0
    CaptureVars Recap(Actions);
5810
0
    Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5811
0
    Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5812
5813
0
    Expr *Skip = AssertSuccess(
5814
0
        Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5815
    // TODO: Explicitly cast to the iterator's difference_type instead of
5816
    // relying on implicit conversion.
5817
0
    Expr *Advanced =
5818
0
        AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5819
5820
0
    if (Deref) {
5821
      // For range-based for-loops convert the loop counter value to a concrete
5822
      // loop variable value by dereferencing the iterator.
5823
0
      Advanced =
5824
0
          AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5825
0
    }
5826
5827
    // Assign the result to the output parameter.
5828
0
    Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5829
0
                                            BO_Assign, TargetRef, Advanced));
5830
0
  }
5831
0
  return cast<CapturedStmt>(
5832
0
      AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5833
0
}
5834
5835
0
StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5836
0
  ASTContext &Ctx = getASTContext();
5837
5838
  // Extract the common elements of ForStmt and CXXForRangeStmt:
5839
  // Loop variable, repeat condition, increment
5840
0
  Expr *Cond, *Inc;
5841
0
  VarDecl *LIVDecl, *LUVDecl;
5842
0
  if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5843
0
    Stmt *Init = For->getInit();
5844
0
    if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5845
      // For statement declares loop variable.
5846
0
      LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5847
0
    } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5848
      // For statement reuses variable.
5849
0
      assert(LCAssign->getOpcode() == BO_Assign &&
5850
0
             "init part must be a loop variable assignment");
5851
0
      auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5852
0
      LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5853
0
    } else
5854
0
      llvm_unreachable("Cannot determine loop variable");
5855
0
    LUVDecl = LIVDecl;
5856
5857
0
    Cond = For->getCond();
5858
0
    Inc = For->getInc();
5859
0
  } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5860
0
    DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5861
0
    LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5862
0
    LUVDecl = RangeFor->getLoopVariable();
5863
5864
0
    Cond = RangeFor->getCond();
5865
0
    Inc = RangeFor->getInc();
5866
0
  } else
5867
0
    llvm_unreachable("unhandled kind of loop");
5868
5869
0
  QualType CounterTy = LIVDecl->getType();
5870
0
  QualType LVTy = LUVDecl->getType();
5871
5872
  // Analyze the loop condition.
5873
0
  Expr *LHS, *RHS;
5874
0
  BinaryOperator::Opcode CondRel;
5875
0
  Cond = Cond->IgnoreImplicit();
5876
0
  if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5877
0
    LHS = CondBinExpr->getLHS();
5878
0
    RHS = CondBinExpr->getRHS();
5879
0
    CondRel = CondBinExpr->getOpcode();
5880
0
  } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5881
0
    assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5882
0
    LHS = CondCXXOp->getArg(0);
5883
0
    RHS = CondCXXOp->getArg(1);
5884
0
    switch (CondCXXOp->getOperator()) {
5885
0
    case OO_ExclaimEqual:
5886
0
      CondRel = BO_NE;
5887
0
      break;
5888
0
    case OO_Less:
5889
0
      CondRel = BO_LT;
5890
0
      break;
5891
0
    case OO_LessEqual:
5892
0
      CondRel = BO_LE;
5893
0
      break;
5894
0
    case OO_Greater:
5895
0
      CondRel = BO_GT;
5896
0
      break;
5897
0
    case OO_GreaterEqual:
5898
0
      CondRel = BO_GE;
5899
0
      break;
5900
0
    default:
5901
0
      llvm_unreachable("unexpected iterator operator");
5902
0
    }
5903
0
  } else
5904
0
    llvm_unreachable("unexpected loop condition");
5905
5906
  // Normalize such that the loop counter is on the LHS.
5907
0
  if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5908
0
      cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5909
0
    std::swap(LHS, RHS);
5910
0
    CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5911
0
  }
5912
0
  auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5913
5914
  // Decide the bit width for the logical iteration counter. By default use the
5915
  // unsigned ptrdiff_t integer size (for iterators and pointers).
5916
  // TODO: For iterators, use iterator::difference_type,
5917
  // std::iterator_traits<>::difference_type or decltype(it - end).
5918
0
  QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5919
0
  if (CounterTy->isIntegerType()) {
5920
0
    unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5921
0
    LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5922
0
  }
5923
5924
  // Analyze the loop increment.
5925
0
  Expr *Step;
5926
0
  if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5927
0
    int Direction;
5928
0
    switch (IncUn->getOpcode()) {
5929
0
    case UO_PreInc:
5930
0
    case UO_PostInc:
5931
0
      Direction = 1;
5932
0
      break;
5933
0
    case UO_PreDec:
5934
0
    case UO_PostDec:
5935
0
      Direction = -1;
5936
0
      break;
5937
0
    default:
5938
0
      llvm_unreachable("unhandled unary increment operator");
5939
0
    }
5940
0
    Step = IntegerLiteral::Create(
5941
0
        Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5942
0
  } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5943
0
    if (IncBin->getOpcode() == BO_AddAssign) {
5944
0
      Step = IncBin->getRHS();
5945
0
    } else if (IncBin->getOpcode() == BO_SubAssign) {
5946
0
      Step =
5947
0
          AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5948
0
    } else
5949
0
      llvm_unreachable("unhandled binary increment operator");
5950
0
  } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5951
0
    switch (CondCXXOp->getOperator()) {
5952
0
    case OO_PlusPlus:
5953
0
      Step = IntegerLiteral::Create(
5954
0
          Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5955
0
      break;
5956
0
    case OO_MinusMinus:
5957
0
      Step = IntegerLiteral::Create(
5958
0
          Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5959
0
      break;
5960
0
    case OO_PlusEqual:
5961
0
      Step = CondCXXOp->getArg(1);
5962
0
      break;
5963
0
    case OO_MinusEqual:
5964
0
      Step = AssertSuccess(
5965
0
          BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5966
0
      break;
5967
0
    default:
5968
0
      llvm_unreachable("unhandled overloaded increment operator");
5969
0
    }
5970
0
  } else
5971
0
    llvm_unreachable("unknown increment expression");
5972
5973
0
  CapturedStmt *DistanceFunc =
5974
0
      buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5975
0
  CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5976
0
      *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5977
0
  DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5978
0
                                        {}, nullptr, nullptr, {}, nullptr);
5979
0
  return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5980
0
                                  LoopVarFunc, LVRef);
5981
0
}
5982
5983
0
StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5984
  // Handle a literal loop.
5985
0
  if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5986
0
    return ActOnOpenMPCanonicalLoop(AStmt);
5987
5988
  // If not a literal loop, it must be the result of a loop transformation.
5989
0
  OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5990
0
  assert(
5991
0
      isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&
5992
0
      "Loop transformation directive expected");
5993
0
  return LoopTransform;
5994
0
}
5995
5996
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5997
                                            CXXScopeSpec &MapperIdScopeSpec,
5998
                                            const DeclarationNameInfo &MapperId,
5999
                                            QualType Type,
6000
                                            Expr *UnresolvedMapper);
6001
6002
/// Perform DFS through the structure/class data members trying to find
6003
/// member(s) with user-defined 'default' mapper and generate implicit map
6004
/// clauses for such members with the found 'default' mapper.
6005
static void
6006
processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
6007
0
                                      SmallVectorImpl<OMPClause *> &Clauses) {
6008
  // Check for the deault mapper for data members.
6009
0
  if (S.getLangOpts().OpenMP < 50)
6010
0
    return;
6011
0
  SmallVector<OMPClause *, 4> ImplicitMaps;
6012
0
  for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
6013
0
    auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
6014
0
    if (!C)
6015
0
      continue;
6016
0
    SmallVector<Expr *, 4> SubExprs;
6017
0
    auto *MI = C->mapperlist_begin();
6018
0
    for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
6019
0
         ++I, ++MI) {
6020
      // Expression is mapped using mapper - skip it.
6021
0
      if (*MI)
6022
0
        continue;
6023
0
      Expr *E = *I;
6024
      // Expression is dependent - skip it, build the mapper when it gets
6025
      // instantiated.
6026
0
      if (E->isTypeDependent() || E->isValueDependent() ||
6027
0
          E->containsUnexpandedParameterPack())
6028
0
        continue;
6029
      // Array section - need to check for the mapping of the array section
6030
      // element.
6031
0
      QualType CanonType = E->getType().getCanonicalType();
6032
0
      if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
6033
0
        const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
6034
0
        QualType BaseType =
6035
0
            OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
6036
0
        QualType ElemType;
6037
0
        if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
6038
0
          ElemType = ATy->getElementType();
6039
0
        else
6040
0
          ElemType = BaseType->getPointeeType();
6041
0
        CanonType = ElemType;
6042
0
      }
6043
6044
      // DFS over data members in structures/classes.
6045
0
      SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
6046
0
          1, {CanonType, nullptr});
6047
0
      llvm::DenseMap<const Type *, Expr *> Visited;
6048
0
      SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
6049
0
          1, {nullptr, 1});
6050
0
      while (!Types.empty()) {
6051
0
        QualType BaseType;
6052
0
        FieldDecl *CurFD;
6053
0
        std::tie(BaseType, CurFD) = Types.pop_back_val();
6054
0
        while (ParentChain.back().second == 0)
6055
0
          ParentChain.pop_back();
6056
0
        --ParentChain.back().second;
6057
0
        if (BaseType.isNull())
6058
0
          continue;
6059
        // Only structs/classes are allowed to have mappers.
6060
0
        const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
6061
0
        if (!RD)
6062
0
          continue;
6063
0
        auto It = Visited.find(BaseType.getTypePtr());
6064
0
        if (It == Visited.end()) {
6065
          // Try to find the associated user-defined mapper.
6066
0
          CXXScopeSpec MapperIdScopeSpec;
6067
0
          DeclarationNameInfo DefaultMapperId;
6068
0
          DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
6069
0
              &S.Context.Idents.get("default")));
6070
0
          DefaultMapperId.setLoc(E->getExprLoc());
6071
0
          ExprResult ER = buildUserDefinedMapperRef(
6072
0
              S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6073
0
              BaseType, /*UnresolvedMapper=*/nullptr);
6074
0
          if (ER.isInvalid())
6075
0
            continue;
6076
0
          It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
6077
0
        }
6078
        // Found default mapper.
6079
0
        if (It->second) {
6080
0
          auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
6081
0
                                                     VK_LValue, OK_Ordinary, E);
6082
0
          OE->setIsUnique(/*V=*/true);
6083
0
          Expr *BaseExpr = OE;
6084
0
          for (const auto &P : ParentChain) {
6085
0
            if (P.first) {
6086
0
              BaseExpr = S.BuildMemberExpr(
6087
0
                  BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6088
0
                  NestedNameSpecifierLoc(), SourceLocation(), P.first,
6089
0
                  DeclAccessPair::make(P.first, P.first->getAccess()),
6090
0
                  /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6091
0
                  P.first->getType(), VK_LValue, OK_Ordinary);
6092
0
              BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
6093
0
            }
6094
0
          }
6095
0
          if (CurFD)
6096
0
            BaseExpr = S.BuildMemberExpr(
6097
0
                BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6098
0
                NestedNameSpecifierLoc(), SourceLocation(), CurFD,
6099
0
                DeclAccessPair::make(CurFD, CurFD->getAccess()),
6100
0
                /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6101
0
                CurFD->getType(), VK_LValue, OK_Ordinary);
6102
0
          SubExprs.push_back(BaseExpr);
6103
0
          continue;
6104
0
        }
6105
        // Check for the "default" mapper for data members.
6106
0
        bool FirstIter = true;
6107
0
        for (FieldDecl *FD : RD->fields()) {
6108
0
          if (!FD)
6109
0
            continue;
6110
0
          QualType FieldTy = FD->getType();
6111
0
          if (FieldTy.isNull() ||
6112
0
              !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
6113
0
            continue;
6114
0
          if (FirstIter) {
6115
0
            FirstIter = false;
6116
0
            ParentChain.emplace_back(CurFD, 1);
6117
0
          } else {
6118
0
            ++ParentChain.back().second;
6119
0
          }
6120
0
          Types.emplace_back(FieldTy, FD);
6121
0
        }
6122
0
      }
6123
0
    }
6124
0
    if (SubExprs.empty())
6125
0
      continue;
6126
0
    CXXScopeSpec MapperIdScopeSpec;
6127
0
    DeclarationNameInfo MapperId;
6128
0
    if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
6129
0
            nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
6130
0
            MapperIdScopeSpec, MapperId, C->getMapType(),
6131
0
            /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6132
0
            SubExprs, OMPVarListLocTy()))
6133
0
      Clauses.push_back(NewClause);
6134
0
  }
6135
0
}
6136
6137
bool Sema::mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
6138
                            ArrayRef<OMPClause *> Clauses,
6139
                            OpenMPBindClauseKind &BindKind,
6140
                            OpenMPDirectiveKind &Kind,
6141
                            OpenMPDirectiveKind &PrevMappedDirective,
6142
                            SourceLocation StartLoc, SourceLocation EndLoc,
6143
                            const DeclarationNameInfo &DirName,
6144
0
                            OpenMPDirectiveKind CancelRegion) {
6145
6146
0
  bool UseClausesWithoutBind = false;
6147
6148
  // Restricting to "#pragma omp loop bind"
6149
0
  if (getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
6150
6151
0
    const OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
6152
6153
0
    if (BindKind == OMPC_BIND_unknown) {
6154
      // Setting the enclosing teams or parallel construct for the loop
6155
      // directive without bind clause.
6156
0
      BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown
6157
6158
0
      if (ParentDirective == OMPD_unknown) {
6159
0
        Diag(DSAStack->getDefaultDSALocation(),
6160
0
             diag::err_omp_bind_required_on_loop);
6161
0
      } else if (ParentDirective == OMPD_parallel ||
6162
0
                 ParentDirective == OMPD_target_parallel) {
6163
0
        BindKind = OMPC_BIND_parallel;
6164
0
      } else if (ParentDirective == OMPD_teams ||
6165
0
                 ParentDirective == OMPD_target_teams) {
6166
0
        BindKind = OMPC_BIND_teams;
6167
0
      }
6168
0
    } else {
6169
      // bind clause is present in loop directive. When the loop directive is
6170
      // changed to a new directive the bind clause is not used. So, we should
6171
      // set flag indicating to only use the clauses that aren't the
6172
      // bind clause.
6173
0
      UseClausesWithoutBind = true;
6174
0
    }
6175
6176
0
    for (OMPClause *C : Clauses) {
6177
      // Spec restriction : bind(teams) and reduction not permitted.
6178
0
      if (BindKind == OMPC_BIND_teams &&
6179
0
          C->getClauseKind() == llvm::omp::Clause::OMPC_reduction)
6180
0
        Diag(DSAStack->getDefaultDSALocation(),
6181
0
             diag::err_omp_loop_reduction_clause);
6182
6183
      // A new Vector ClausesWithoutBind, which does not contain the bind
6184
      // clause, for passing to new directive.
6185
0
      if (C->getClauseKind() != llvm::omp::Clause::OMPC_bind)
6186
0
        ClausesWithoutBind.push_back(C);
6187
0
    }
6188
6189
0
    switch (BindKind) {
6190
0
    case OMPC_BIND_parallel:
6191
0
      Kind = OMPD_for;
6192
0
      DSAStack->setCurrentDirective(OMPD_for);
6193
0
      DSAStack->setMappedDirective(OMPD_loop);
6194
0
      PrevMappedDirective = OMPD_loop;
6195
0
      break;
6196
0
    case OMPC_BIND_teams:
6197
0
      Kind = OMPD_distribute;
6198
0
      DSAStack->setCurrentDirective(OMPD_distribute);
6199
0
      DSAStack->setMappedDirective(OMPD_loop);
6200
0
      PrevMappedDirective = OMPD_loop;
6201
0
      break;
6202
0
    case OMPC_BIND_thread:
6203
0
      Kind = OMPD_simd;
6204
0
      DSAStack->setCurrentDirective(OMPD_simd);
6205
0
      DSAStack->setMappedDirective(OMPD_loop);
6206
0
      PrevMappedDirective = OMPD_loop;
6207
0
      break;
6208
0
    case OMPC_BIND_unknown:
6209
0
      break;
6210
0
    }
6211
0
  } else if (PrevMappedDirective == OMPD_loop) {
6212
    /// An initial pass after recognizing all the statements is done in the
6213
    /// Parser when the directive OMPD_loop is mapped to OMPD_for,
6214
    /// OMPD_distribute or OMPD_simd. A second transform pass with call from
6215
    /// clang::TreeTransform::TransformOMPExecutableDirective() is done
6216
    /// with the Directive as one of the above mapped directive without
6217
    /// the bind clause. Then "PrevMappedDirective" stored in the
6218
    /// OMPExecutableDirective is accessed and hence this else statement.
6219
6220
0
    DSAStack->setMappedDirective(OMPD_loop);
6221
0
  }
6222
6223
0
  return UseClausesWithoutBind;
6224
0
}
6225
6226
StmtResult Sema::ActOnOpenMPExecutableDirective(
6227
    OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
6228
    OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
6229
    Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
6230
0
    OpenMPDirectiveKind PrevMappedDirective) {
6231
0
  StmtResult Res = StmtError();
6232
0
  OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
6233
0
  llvm::SmallVector<OMPClause *> ClausesWithoutBind;
6234
0
  bool UseClausesWithoutBind = false;
6235
6236
0
  if (const OMPBindClause *BC =
6237
0
          OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6238
0
    BindKind = BC->getBindKind();
6239
6240
  // Variable used to note down the DirectiveKind because mapLoopConstruct may
6241
  // change "Kind" variable, due to mapping of "omp loop" to other directives.
6242
0
  OpenMPDirectiveKind DK = Kind;
6243
0
  if (Kind == OMPD_loop || PrevMappedDirective == OMPD_loop) {
6244
0
    UseClausesWithoutBind = mapLoopConstruct(
6245
0
        ClausesWithoutBind, Clauses, BindKind, Kind, PrevMappedDirective,
6246
0
        StartLoc, EndLoc, DirName, CancelRegion);
6247
0
    DK = OMPD_loop;
6248
0
  }
6249
6250
  // First check CancelRegion which is then used in checkNestingOfRegions.
6251
0
  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6252
0
      checkNestingOfRegions(*this, DSAStack, DK, DirName, CancelRegion,
6253
0
                            BindKind, StartLoc)) {
6254
0
    return StmtError();
6255
0
  }
6256
6257
  // Report affected OpenMP target offloading behavior when in HIP lang-mode.
6258
0
  if (getLangOpts().HIP && (isOpenMPTargetExecutionDirective(Kind) ||
6259
0
                            isOpenMPTargetDataManagementDirective(Kind)))
6260
0
    Diag(StartLoc, diag::warn_hip_omp_target_directives);
6261
6262
0
  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
6263
0
  VarsWithInheritedDSAType VarsWithInheritedDSA;
6264
0
  bool ErrorFound = false;
6265
0
  if (getLangOpts().OpenMP >= 50 && UseClausesWithoutBind) {
6266
0
    ClausesWithImplicit.append(ClausesWithoutBind.begin(),
6267
0
                               ClausesWithoutBind.end());
6268
0
  } else {
6269
0
    ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6270
0
  }
6271
0
  if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
6272
0
      Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
6273
0
      Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
6274
0
    assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6275
6276
    // Check default data sharing attributes for referenced variables.
6277
0
    DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
6278
0
    int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6279
0
    Stmt *S = AStmt;
6280
0
    while (--ThisCaptureLevel >= 0)
6281
0
      S = cast<CapturedStmt>(S)->getCapturedStmt();
6282
0
    DSAChecker.Visit(S);
6283
0
    if (!isOpenMPTargetDataManagementDirective(Kind) &&
6284
0
        !isOpenMPTaskingDirective(Kind)) {
6285
      // Visit subcaptures to generate implicit clauses for captured vars.
6286
0
      auto *CS = cast<CapturedStmt>(AStmt);
6287
0
      SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
6288
0
      getOpenMPCaptureRegions(CaptureRegions, Kind);
6289
      // Ignore outer tasking regions for target directives.
6290
0
      if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6291
0
        CS = cast<CapturedStmt>(CS->getCapturedStmt());
6292
0
      DSAChecker.visitSubCaptures(CS);
6293
0
    }
6294
0
    if (DSAChecker.isErrorFound())
6295
0
      return StmtError();
6296
    // Generate list of implicitly defined firstprivate variables.
6297
0
    VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6298
6299
0
    SmallVector<Expr *, 4> ImplicitFirstprivates(
6300
0
        DSAChecker.getImplicitFirstprivate().begin(),
6301
0
        DSAChecker.getImplicitFirstprivate().end());
6302
0
    SmallVector<Expr *, 4> ImplicitPrivates(
6303
0
        DSAChecker.getImplicitPrivate().begin(),
6304
0
        DSAChecker.getImplicitPrivate().end());
6305
0
    const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
6306
0
    SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
6307
0
    SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
6308
0
        ImplicitMapModifiers[DefaultmapKindNum];
6309
0
    SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
6310
0
        ImplicitMapModifiersLoc[DefaultmapKindNum];
6311
    // Get the original location of present modifier from Defaultmap clause.
6312
0
    SourceLocation PresentModifierLocs[DefaultmapKindNum];
6313
0
    for (OMPClause *C : Clauses) {
6314
0
      if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
6315
0
        if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6316
0
          PresentModifierLocs[DMC->getDefaultmapKind()] =
6317
0
              DMC->getDefaultmapModifierLoc();
6318
0
    }
6319
0
    for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6320
0
      auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
6321
0
      for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6322
0
        ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
6323
0
            Kind, static_cast<OpenMPMapClauseKind>(I));
6324
0
        ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6325
0
      }
6326
0
      ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
6327
0
          DSAChecker.getImplicitMapModifier(Kind);
6328
0
      ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6329
0
                                      ImplicitModifier.end());
6330
0
      std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6331
0
                  ImplicitModifier.size(), PresentModifierLocs[VC]);
6332
0
    }
6333
    // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6334
0
    for (OMPClause *C : Clauses) {
6335
0
      if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
6336
0
        for (Expr *E : IRC->taskgroup_descriptors())
6337
0
          if (E)
6338
0
            ImplicitFirstprivates.emplace_back(E);
6339
0
      }
6340
      // OpenMP 5.0, 2.10.1 task Construct
6341
      // [detach clause]... The event-handle will be considered as if it was
6342
      // specified on a firstprivate clause.
6343
0
      if (auto *DC = dyn_cast<OMPDetachClause>(C))
6344
0
        ImplicitFirstprivates.push_back(DC->getEventHandler());
6345
0
    }
6346
0
    if (!ImplicitFirstprivates.empty()) {
6347
0
      if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6348
0
              ImplicitFirstprivates, SourceLocation(), SourceLocation(),
6349
0
              SourceLocation())) {
6350
0
        ClausesWithImplicit.push_back(Implicit);
6351
0
        ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6352
0
                     ImplicitFirstprivates.size();
6353
0
      } else {
6354
0
        ErrorFound = true;
6355
0
      }
6356
0
    }
6357
0
    if (!ImplicitPrivates.empty()) {
6358
0
      if (OMPClause *Implicit =
6359
0
              ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(),
6360
0
                                       SourceLocation(), SourceLocation())) {
6361
0
        ClausesWithImplicit.push_back(Implicit);
6362
0
        ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6363
0
                     ImplicitPrivates.size();
6364
0
      } else {
6365
0
        ErrorFound = true;
6366
0
      }
6367
0
    }
6368
    // OpenMP 5.0 [2.19.7]
6369
    // If a list item appears in a reduction, lastprivate or linear
6370
    // clause on a combined target construct then it is treated as
6371
    // if it also appears in a map clause with a map-type of tofrom
6372
0
    if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6373
0
        isOpenMPTargetExecutionDirective(Kind)) {
6374
0
      SmallVector<Expr *, 4> ImplicitExprs;
6375
0
      for (OMPClause *C : Clauses) {
6376
0
        if (auto *RC = dyn_cast<OMPReductionClause>(C))
6377
0
          for (Expr *E : RC->varlists())
6378
0
            if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
6379
0
              ImplicitExprs.emplace_back(E);
6380
0
      }
6381
0
      if (!ImplicitExprs.empty()) {
6382
0
        ArrayRef<Expr *> Exprs = ImplicitExprs;
6383
0
        CXXScopeSpec MapperIdScopeSpec;
6384
0
        DeclarationNameInfo MapperId;
6385
0
        if (OMPClause *Implicit = ActOnOpenMPMapClause(
6386
0
                nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(),
6387
0
                MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6388
0
                /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6389
0
                Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
6390
0
          ClausesWithImplicit.emplace_back(Implicit);
6391
0
      }
6392
0
    }
6393
0
    for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6394
0
      int ClauseKindCnt = -1;
6395
0
      for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
6396
0
        ++ClauseKindCnt;
6397
0
        if (ImplicitMap.empty())
6398
0
          continue;
6399
0
        CXXScopeSpec MapperIdScopeSpec;
6400
0
        DeclarationNameInfo MapperId;
6401
0
        auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
6402
0
        if (OMPClause *Implicit = ActOnOpenMPMapClause(
6403
0
                nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6404
0
                MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
6405
0
                SourceLocation(), SourceLocation(), ImplicitMap,
6406
0
                OMPVarListLocTy())) {
6407
0
          ClausesWithImplicit.emplace_back(Implicit);
6408
0
          ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6409
0
                        ImplicitMap.size();
6410
0
        } else {
6411
0
          ErrorFound = true;
6412
0
        }
6413
0
      }
6414
0
    }
6415
    // Build expressions for implicit maps of data members with 'default'
6416
    // mappers.
6417
0
    if (LangOpts.OpenMP >= 50)
6418
0
      processImplicitMapsWithDefaultMappers(*this, DSAStack,
6419
0
                                            ClausesWithImplicit);
6420
0
  }
6421
6422
0
  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
6423
0
  switch (Kind) {
6424
0
  case OMPD_parallel:
6425
0
    Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6426
0
                                       EndLoc);
6427
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6428
0
    break;
6429
0
  case OMPD_simd:
6430
0
    Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6431
0
                                   VarsWithInheritedDSA);
6432
0
    if (LangOpts.OpenMP >= 50)
6433
0
      AllowedNameModifiers.push_back(OMPD_simd);
6434
0
    break;
6435
0
  case OMPD_tile:
6436
0
    Res =
6437
0
        ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6438
0
    break;
6439
0
  case OMPD_unroll:
6440
0
    Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6441
0
                                     EndLoc);
6442
0
    break;
6443
0
  case OMPD_for:
6444
0
    Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6445
0
                                  VarsWithInheritedDSA);
6446
0
    break;
6447
0
  case OMPD_for_simd:
6448
0
    Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6449
0
                                      EndLoc, VarsWithInheritedDSA);
6450
0
    if (LangOpts.OpenMP >= 50)
6451
0
      AllowedNameModifiers.push_back(OMPD_simd);
6452
0
    break;
6453
0
  case OMPD_sections:
6454
0
    Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6455
0
                                       EndLoc);
6456
0
    break;
6457
0
  case OMPD_section:
6458
0
    assert(ClausesWithImplicit.empty() &&
6459
0
           "No clauses are allowed for 'omp section' directive");
6460
0
    Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6461
0
    break;
6462
0
  case OMPD_single:
6463
0
    Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6464
0
                                     EndLoc);
6465
0
    break;
6466
0
  case OMPD_master:
6467
0
    assert(ClausesWithImplicit.empty() &&
6468
0
           "No clauses are allowed for 'omp master' directive");
6469
0
    Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6470
0
    break;
6471
0
  case OMPD_masked:
6472
0
    Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6473
0
                                     EndLoc);
6474
0
    break;
6475
0
  case OMPD_critical:
6476
0
    Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6477
0
                                       StartLoc, EndLoc);
6478
0
    break;
6479
0
  case OMPD_parallel_for:
6480
0
    Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6481
0
                                          EndLoc, VarsWithInheritedDSA);
6482
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6483
0
    break;
6484
0
  case OMPD_parallel_for_simd:
6485
0
    Res = ActOnOpenMPParallelForSimdDirective(
6486
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6487
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6488
0
    if (LangOpts.OpenMP >= 50)
6489
0
      AllowedNameModifiers.push_back(OMPD_simd);
6490
0
    break;
6491
0
  case OMPD_scope:
6492
0
    Res =
6493
0
        ActOnOpenMPScopeDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6494
0
    break;
6495
0
  case OMPD_parallel_master:
6496
0
    Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6497
0
                                             StartLoc, EndLoc);
6498
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6499
0
    break;
6500
0
  case OMPD_parallel_masked:
6501
0
    Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6502
0
                                             StartLoc, EndLoc);
6503
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6504
0
    break;
6505
0
  case OMPD_parallel_sections:
6506
0
    Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6507
0
                                               StartLoc, EndLoc);
6508
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6509
0
    break;
6510
0
  case OMPD_task:
6511
0
    Res =
6512
0
        ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6513
0
    AllowedNameModifiers.push_back(OMPD_task);
6514
0
    break;
6515
0
  case OMPD_taskyield:
6516
0
    assert(ClausesWithImplicit.empty() &&
6517
0
           "No clauses are allowed for 'omp taskyield' directive");
6518
0
    assert(AStmt == nullptr &&
6519
0
           "No associated statement allowed for 'omp taskyield' directive");
6520
0
    Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6521
0
    break;
6522
0
  case OMPD_error:
6523
0
    assert(AStmt == nullptr &&
6524
0
           "No associated statement allowed for 'omp error' directive");
6525
0
    Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
6526
0
    break;
6527
0
  case OMPD_barrier:
6528
0
    assert(ClausesWithImplicit.empty() &&
6529
0
           "No clauses are allowed for 'omp barrier' directive");
6530
0
    assert(AStmt == nullptr &&
6531
0
           "No associated statement allowed for 'omp barrier' directive");
6532
0
    Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6533
0
    break;
6534
0
  case OMPD_taskwait:
6535
0
    assert(AStmt == nullptr &&
6536
0
           "No associated statement allowed for 'omp taskwait' directive");
6537
0
    Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6538
0
    break;
6539
0
  case OMPD_taskgroup:
6540
0
    Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6541
0
                                        EndLoc);
6542
0
    break;
6543
0
  case OMPD_flush:
6544
0
    assert(AStmt == nullptr &&
6545
0
           "No associated statement allowed for 'omp flush' directive");
6546
0
    Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6547
0
    break;
6548
0
  case OMPD_depobj:
6549
0
    assert(AStmt == nullptr &&
6550
0
           "No associated statement allowed for 'omp depobj' directive");
6551
0
    Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6552
0
    break;
6553
0
  case OMPD_scan:
6554
0
    assert(AStmt == nullptr &&
6555
0
           "No associated statement allowed for 'omp scan' directive");
6556
0
    Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6557
0
    break;
6558
0
  case OMPD_ordered:
6559
0
    Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6560
0
                                      EndLoc);
6561
0
    break;
6562
0
  case OMPD_atomic:
6563
0
    Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6564
0
                                     EndLoc);
6565
0
    break;
6566
0
  case OMPD_teams:
6567
0
    Res =
6568
0
        ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6569
0
    break;
6570
0
  case OMPD_target:
6571
0
    Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6572
0
                                     EndLoc);
6573
0
    AllowedNameModifiers.push_back(OMPD_target);
6574
0
    break;
6575
0
  case OMPD_target_parallel:
6576
0
    Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6577
0
                                             StartLoc, EndLoc);
6578
0
    AllowedNameModifiers.push_back(OMPD_target);
6579
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6580
0
    break;
6581
0
  case OMPD_target_parallel_for:
6582
0
    Res = ActOnOpenMPTargetParallelForDirective(
6583
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6584
0
    AllowedNameModifiers.push_back(OMPD_target);
6585
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6586
0
    break;
6587
0
  case OMPD_cancellation_point:
6588
0
    assert(ClausesWithImplicit.empty() &&
6589
0
           "No clauses are allowed for 'omp cancellation point' directive");
6590
0
    assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6591
0
                               "cancellation point' directive");
6592
0
    Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6593
0
    break;
6594
0
  case OMPD_cancel:
6595
0
    assert(AStmt == nullptr &&
6596
0
           "No associated statement allowed for 'omp cancel' directive");
6597
0
    Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6598
0
                                     CancelRegion);
6599
0
    AllowedNameModifiers.push_back(OMPD_cancel);
6600
0
    break;
6601
0
  case OMPD_target_data:
6602
0
    Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6603
0
                                         EndLoc);
6604
0
    AllowedNameModifiers.push_back(OMPD_target_data);
6605
0
    break;
6606
0
  case OMPD_target_enter_data:
6607
0
    Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6608
0
                                              EndLoc, AStmt);
6609
0
    AllowedNameModifiers.push_back(OMPD_target_enter_data);
6610
0
    break;
6611
0
  case OMPD_target_exit_data:
6612
0
    Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6613
0
                                             EndLoc, AStmt);
6614
0
    AllowedNameModifiers.push_back(OMPD_target_exit_data);
6615
0
    break;
6616
0
  case OMPD_taskloop:
6617
0
    Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6618
0
                                       EndLoc, VarsWithInheritedDSA);
6619
0
    AllowedNameModifiers.push_back(OMPD_taskloop);
6620
0
    break;
6621
0
  case OMPD_taskloop_simd:
6622
0
    Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6623
0
                                           EndLoc, VarsWithInheritedDSA);
6624
0
    AllowedNameModifiers.push_back(OMPD_taskloop);
6625
0
    if (LangOpts.OpenMP >= 50)
6626
0
      AllowedNameModifiers.push_back(OMPD_simd);
6627
0
    break;
6628
0
  case OMPD_master_taskloop:
6629
0
    Res = ActOnOpenMPMasterTaskLoopDirective(
6630
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6631
0
    AllowedNameModifiers.push_back(OMPD_taskloop);
6632
0
    break;
6633
0
  case OMPD_masked_taskloop:
6634
0
    Res = ActOnOpenMPMaskedTaskLoopDirective(
6635
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6636
0
    AllowedNameModifiers.push_back(OMPD_taskloop);
6637
0
    break;
6638
0
  case OMPD_master_taskloop_simd:
6639
0
    Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6640
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6641
0
    AllowedNameModifiers.push_back(OMPD_taskloop);
6642
0
    if (LangOpts.OpenMP >= 50)
6643
0
      AllowedNameModifiers.push_back(OMPD_simd);
6644
0
    break;
6645
0
  case OMPD_masked_taskloop_simd:
6646
0
    Res = ActOnOpenMPMaskedTaskLoopSimdDirective(
6647
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6648
0
    if (LangOpts.OpenMP >= 51) {
6649
0
      AllowedNameModifiers.push_back(OMPD_taskloop);
6650
0
      AllowedNameModifiers.push_back(OMPD_simd);
6651
0
    }
6652
0
    break;
6653
0
  case OMPD_parallel_master_taskloop:
6654
0
    Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6655
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6656
0
    AllowedNameModifiers.push_back(OMPD_taskloop);
6657
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6658
0
    break;
6659
0
  case OMPD_parallel_masked_taskloop:
6660
0
    Res = ActOnOpenMPParallelMaskedTaskLoopDirective(
6661
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6662
0
    if (LangOpts.OpenMP >= 51) {
6663
0
      AllowedNameModifiers.push_back(OMPD_taskloop);
6664
0
      AllowedNameModifiers.push_back(OMPD_parallel);
6665
0
    }
6666
0
    break;
6667
0
  case OMPD_parallel_master_taskloop_simd:
6668
0
    Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6669
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6670
0
    AllowedNameModifiers.push_back(OMPD_taskloop);
6671
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6672
0
    if (LangOpts.OpenMP >= 50)
6673
0
      AllowedNameModifiers.push_back(OMPD_simd);
6674
0
    break;
6675
0
  case OMPD_parallel_masked_taskloop_simd:
6676
0
    Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6677
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6678
0
    if (LangOpts.OpenMP >= 51) {
6679
0
      AllowedNameModifiers.push_back(OMPD_taskloop);
6680
0
      AllowedNameModifiers.push_back(OMPD_parallel);
6681
0
      AllowedNameModifiers.push_back(OMPD_simd);
6682
0
    }
6683
0
    break;
6684
0
  case OMPD_distribute:
6685
0
    Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6686
0
                                         EndLoc, VarsWithInheritedDSA);
6687
0
    break;
6688
0
  case OMPD_target_update:
6689
0
    Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6690
0
                                           EndLoc, AStmt);
6691
0
    AllowedNameModifiers.push_back(OMPD_target_update);
6692
0
    break;
6693
0
  case OMPD_distribute_parallel_for:
6694
0
    Res = ActOnOpenMPDistributeParallelForDirective(
6695
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6696
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6697
0
    break;
6698
0
  case OMPD_distribute_parallel_for_simd:
6699
0
    Res = ActOnOpenMPDistributeParallelForSimdDirective(
6700
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6701
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6702
0
    if (LangOpts.OpenMP >= 50)
6703
0
      AllowedNameModifiers.push_back(OMPD_simd);
6704
0
    break;
6705
0
  case OMPD_distribute_simd:
6706
0
    Res = ActOnOpenMPDistributeSimdDirective(
6707
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6708
0
    if (LangOpts.OpenMP >= 50)
6709
0
      AllowedNameModifiers.push_back(OMPD_simd);
6710
0
    break;
6711
0
  case OMPD_target_parallel_for_simd:
6712
0
    Res = ActOnOpenMPTargetParallelForSimdDirective(
6713
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6714
0
    AllowedNameModifiers.push_back(OMPD_target);
6715
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6716
0
    if (LangOpts.OpenMP >= 50)
6717
0
      AllowedNameModifiers.push_back(OMPD_simd);
6718
0
    break;
6719
0
  case OMPD_target_simd:
6720
0
    Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6721
0
                                         EndLoc, VarsWithInheritedDSA);
6722
0
    AllowedNameModifiers.push_back(OMPD_target);
6723
0
    if (LangOpts.OpenMP >= 50)
6724
0
      AllowedNameModifiers.push_back(OMPD_simd);
6725
0
    break;
6726
0
  case OMPD_teams_distribute:
6727
0
    Res = ActOnOpenMPTeamsDistributeDirective(
6728
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6729
0
    break;
6730
0
  case OMPD_teams_distribute_simd:
6731
0
    Res = ActOnOpenMPTeamsDistributeSimdDirective(
6732
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6733
0
    if (LangOpts.OpenMP >= 50)
6734
0
      AllowedNameModifiers.push_back(OMPD_simd);
6735
0
    break;
6736
0
  case OMPD_teams_distribute_parallel_for_simd:
6737
0
    Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6738
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6739
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6740
0
    if (LangOpts.OpenMP >= 50)
6741
0
      AllowedNameModifiers.push_back(OMPD_simd);
6742
0
    break;
6743
0
  case OMPD_teams_distribute_parallel_for:
6744
0
    Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6745
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6746
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6747
0
    break;
6748
0
  case OMPD_target_teams:
6749
0
    Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6750
0
                                          EndLoc);
6751
0
    AllowedNameModifiers.push_back(OMPD_target);
6752
0
    break;
6753
0
  case OMPD_target_teams_distribute:
6754
0
    Res = ActOnOpenMPTargetTeamsDistributeDirective(
6755
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6756
0
    AllowedNameModifiers.push_back(OMPD_target);
6757
0
    break;
6758
0
  case OMPD_target_teams_distribute_parallel_for:
6759
0
    Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6760
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6761
0
    AllowedNameModifiers.push_back(OMPD_target);
6762
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6763
0
    break;
6764
0
  case OMPD_target_teams_distribute_parallel_for_simd:
6765
0
    Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6766
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6767
0
    AllowedNameModifiers.push_back(OMPD_target);
6768
0
    AllowedNameModifiers.push_back(OMPD_parallel);
6769
0
    if (LangOpts.OpenMP >= 50)
6770
0
      AllowedNameModifiers.push_back(OMPD_simd);
6771
0
    break;
6772
0
  case OMPD_target_teams_distribute_simd:
6773
0
    Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6774
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6775
0
    AllowedNameModifiers.push_back(OMPD_target);
6776
0
    if (LangOpts.OpenMP >= 50)
6777
0
      AllowedNameModifiers.push_back(OMPD_simd);
6778
0
    break;
6779
0
  case OMPD_interop:
6780
0
    assert(AStmt == nullptr &&
6781
0
           "No associated statement allowed for 'omp interop' directive");
6782
0
    Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6783
0
    break;
6784
0
  case OMPD_dispatch:
6785
0
    Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6786
0
                                       EndLoc);
6787
0
    break;
6788
0
  case OMPD_loop:
6789
0
    Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6790
0
                                          EndLoc, VarsWithInheritedDSA);
6791
0
    break;
6792
0
  case OMPD_teams_loop:
6793
0
    Res = ActOnOpenMPTeamsGenericLoopDirective(
6794
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6795
0
    break;
6796
0
  case OMPD_target_teams_loop:
6797
0
    Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6798
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6799
0
    AllowedNameModifiers.push_back(OMPD_target);
6800
0
    break;
6801
0
  case OMPD_parallel_loop:
6802
0
    Res = ActOnOpenMPParallelGenericLoopDirective(
6803
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6804
0
    break;
6805
0
  case OMPD_target_parallel_loop:
6806
0
    Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6807
0
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6808
0
    break;
6809
0
  case OMPD_declare_target:
6810
0
  case OMPD_end_declare_target:
6811
0
  case OMPD_threadprivate:
6812
0
  case OMPD_allocate:
6813
0
  case OMPD_declare_reduction:
6814
0
  case OMPD_declare_mapper:
6815
0
  case OMPD_declare_simd:
6816
0
  case OMPD_requires:
6817
0
  case OMPD_declare_variant:
6818
0
  case OMPD_begin_declare_variant:
6819
0
  case OMPD_end_declare_variant:
6820
0
    llvm_unreachable("OpenMP Directive is not allowed");
6821
0
  case OMPD_unknown:
6822
0
  default:
6823
0
    llvm_unreachable("Unknown OpenMP directive");
6824
0
  }
6825
6826
0
  ErrorFound = Res.isInvalid() || ErrorFound;
6827
6828
  // Check variables in the clauses if default(none) or
6829
  // default(firstprivate) was specified.
6830
0
  if (DSAStack->getDefaultDSA() == DSA_none ||
6831
0
      DSAStack->getDefaultDSA() == DSA_private ||
6832
0
      DSAStack->getDefaultDSA() == DSA_firstprivate) {
6833
0
    DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6834
0
    for (OMPClause *C : Clauses) {
6835
0
      switch (C->getClauseKind()) {
6836
0
      case OMPC_num_threads:
6837
0
      case OMPC_dist_schedule:
6838
        // Do not analyse if no parent teams directive.
6839
0
        if (isOpenMPTeamsDirective(Kind))
6840
0
          break;
6841
0
        continue;
6842
0
      case OMPC_if:
6843
0
        if (isOpenMPTeamsDirective(Kind) &&
6844
0
            cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6845
0
          break;
6846
0
        if (isOpenMPParallelDirective(Kind) &&
6847
0
            isOpenMPTaskLoopDirective(Kind) &&
6848
0
            cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6849
0
          break;
6850
0
        continue;
6851
0
      case OMPC_schedule:
6852
0
      case OMPC_detach:
6853
0
        break;
6854
0
      case OMPC_grainsize:
6855
0
      case OMPC_num_tasks:
6856
0
      case OMPC_final:
6857
0
      case OMPC_priority:
6858
0
      case OMPC_novariants:
6859
0
      case OMPC_nocontext:
6860
        // Do not analyze if no parent parallel directive.
6861
0
        if (isOpenMPParallelDirective(Kind))
6862
0
          break;
6863
0
        continue;
6864
0
      case OMPC_ordered:
6865
0
      case OMPC_device:
6866
0
      case OMPC_num_teams:
6867
0
      case OMPC_thread_limit:
6868
0
      case OMPC_hint:
6869
0
      case OMPC_collapse:
6870
0
      case OMPC_safelen:
6871
0
      case OMPC_simdlen:
6872
0
      case OMPC_sizes:
6873
0
      case OMPC_default:
6874
0
      case OMPC_proc_bind:
6875
0
      case OMPC_private:
6876
0
      case OMPC_firstprivate:
6877
0
      case OMPC_lastprivate:
6878
0
      case OMPC_shared:
6879
0
      case OMPC_reduction:
6880
0
      case OMPC_task_reduction:
6881
0
      case OMPC_in_reduction:
6882
0
      case OMPC_linear:
6883
0
      case OMPC_aligned:
6884
0
      case OMPC_copyin:
6885
0
      case OMPC_copyprivate:
6886
0
      case OMPC_nowait:
6887
0
      case OMPC_untied:
6888
0
      case OMPC_mergeable:
6889
0
      case OMPC_allocate:
6890
0
      case OMPC_read:
6891
0
      case OMPC_write:
6892
0
      case OMPC_update:
6893
0
      case OMPC_capture:
6894
0
      case OMPC_compare:
6895
0
      case OMPC_seq_cst:
6896
0
      case OMPC_acq_rel:
6897
0
      case OMPC_acquire:
6898
0
      case OMPC_release:
6899
0
      case OMPC_relaxed:
6900
0
      case OMPC_depend:
6901
0
      case OMPC_threads:
6902
0
      case OMPC_simd:
6903
0
      case OMPC_map:
6904
0
      case OMPC_nogroup:
6905
0
      case OMPC_defaultmap:
6906
0
      case OMPC_to:
6907
0
      case OMPC_from:
6908
0
      case OMPC_use_device_ptr:
6909
0
      case OMPC_use_device_addr:
6910
0
      case OMPC_is_device_ptr:
6911
0
      case OMPC_has_device_addr:
6912
0
      case OMPC_nontemporal:
6913
0
      case OMPC_order:
6914
0
      case OMPC_destroy:
6915
0
      case OMPC_inclusive:
6916
0
      case OMPC_exclusive:
6917
0
      case OMPC_uses_allocators:
6918
0
      case OMPC_affinity:
6919
0
      case OMPC_bind:
6920
0
      case OMPC_filter:
6921
0
        continue;
6922
0
      case OMPC_allocator:
6923
0
      case OMPC_flush:
6924
0
      case OMPC_depobj:
6925
0
      case OMPC_threadprivate:
6926
0
      case OMPC_uniform:
6927
0
      case OMPC_unknown:
6928
0
      case OMPC_unified_address:
6929
0
      case OMPC_unified_shared_memory:
6930
0
      case OMPC_reverse_offload:
6931
0
      case OMPC_dynamic_allocators:
6932
0
      case OMPC_atomic_default_mem_order:
6933
0
      case OMPC_device_type:
6934
0
      case OMPC_match:
6935
0
      case OMPC_when:
6936
0
      case OMPC_at:
6937
0
      case OMPC_severity:
6938
0
      case OMPC_message:
6939
0
      default:
6940
0
        llvm_unreachable("Unexpected clause");
6941
0
      }
6942
0
      for (Stmt *CC : C->children()) {
6943
0
        if (CC)
6944
0
          DSAChecker.Visit(CC);
6945
0
      }
6946
0
    }
6947
0
    for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6948
0
      VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6949
0
  }
6950
0
  for (const auto &P : VarsWithInheritedDSA) {
6951
0
    if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6952
0
      continue;
6953
0
    ErrorFound = true;
6954
0
    if (DSAStack->getDefaultDSA() == DSA_none ||
6955
0
        DSAStack->getDefaultDSA() == DSA_private ||
6956
0
        DSAStack->getDefaultDSA() == DSA_firstprivate) {
6957
0
      Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6958
0
          << P.first << P.second->getSourceRange();
6959
0
      Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6960
0
    } else if (getLangOpts().OpenMP >= 50) {
6961
0
      Diag(P.second->getExprLoc(),
6962
0
           diag::err_omp_defaultmap_no_attr_for_variable)
6963
0
          << P.first << P.second->getSourceRange();
6964
0
      Diag(DSAStack->getDefaultDSALocation(),
6965
0
           diag::note_omp_defaultmap_attr_none);
6966
0
    }
6967
0
  }
6968
6969
0
  if (!AllowedNameModifiers.empty())
6970
0
    ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6971
0
                 ErrorFound;
6972
6973
0
  if (ErrorFound)
6974
0
    return StmtError();
6975
6976
0
  if (!CurContext->isDependentContext() &&
6977
0
      isOpenMPTargetExecutionDirective(Kind) &&
6978
0
      !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6979
0
        DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6980
0
        DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6981
0
        DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6982
    // Register target to DSA Stack.
6983
0
    DSAStack->addTargetDirLocation(StartLoc);
6984
0
  }
6985
6986
0
  return Res;
6987
0
}
6988
6989
Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6990
    DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6991
    ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6992
    ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6993
0
    ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6994
0
  assert(Aligneds.size() == Alignments.size());
6995
0
  assert(Linears.size() == LinModifiers.size());
6996
0
  assert(Linears.size() == Steps.size());
6997
0
  if (!DG || DG.get().isNull())
6998
0
    return DeclGroupPtrTy();
6999
7000
0
  const int SimdId = 0;
7001
0
  if (!DG.get().isSingleDecl()) {
7002
0
    Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7003
0
        << SimdId;
7004
0
    return DG;
7005
0
  }
7006
0
  Decl *ADecl = DG.get().getSingleDecl();
7007
0
  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7008
0
    ADecl = FTD->getTemplatedDecl();
7009
7010
0
  auto *FD = dyn_cast<FunctionDecl>(ADecl);
7011
0
  if (!FD) {
7012
0
    Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
7013
0
    return DeclGroupPtrTy();
7014
0
  }
7015
7016
  // OpenMP [2.8.2, declare simd construct, Description]
7017
  // The parameter of the simdlen clause must be a constant positive integer
7018
  // expression.
7019
0
  ExprResult SL;
7020
0
  if (Simdlen)
7021
0
    SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
7022
  // OpenMP [2.8.2, declare simd construct, Description]
7023
  // The special this pointer can be used as if was one of the arguments to the
7024
  // function in any of the linear, aligned, or uniform clauses.
7025
  // The uniform clause declares one or more arguments to have an invariant
7026
  // value for all concurrent invocations of the function in the execution of a
7027
  // single SIMD loop.
7028
0
  llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
7029
0
  const Expr *UniformedLinearThis = nullptr;
7030
0
  for (const Expr *E : Uniforms) {
7031
0
    E = E->IgnoreParenImpCasts();
7032
0
    if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7033
0
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
7034
0
        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7035
0
            FD->getParamDecl(PVD->getFunctionScopeIndex())
7036
0
                    ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
7037
0
          UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
7038
0
          continue;
7039
0
        }
7040
0
    if (isa<CXXThisExpr>(E)) {
7041
0
      UniformedLinearThis = E;
7042
0
      continue;
7043
0
    }
7044
0
    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7045
0
        << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7046
0
  }
7047
  // OpenMP [2.8.2, declare simd construct, Description]
7048
  // The aligned clause declares that the object to which each list item points
7049
  // is aligned to the number of bytes expressed in the optional parameter of
7050
  // the aligned clause.
7051
  // The special this pointer can be used as if was one of the arguments to the
7052
  // function in any of the linear, aligned, or uniform clauses.
7053
  // The type of list items appearing in the aligned clause must be array,
7054
  // pointer, reference to array, or reference to pointer.
7055
0
  llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
7056
0
  const Expr *AlignedThis = nullptr;
7057
0
  for (const Expr *E : Aligneds) {
7058
0
    E = E->IgnoreParenImpCasts();
7059
0
    if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7060
0
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7061
0
        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7062
0
        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7063
0
            FD->getParamDecl(PVD->getFunctionScopeIndex())
7064
0
                    ->getCanonicalDecl() == CanonPVD) {
7065
          // OpenMP  [2.8.1, simd construct, Restrictions]
7066
          // A list-item cannot appear in more than one aligned clause.
7067
0
          if (AlignedArgs.count(CanonPVD) > 0) {
7068
0
            Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
7069
0
                << 1 << getOpenMPClauseName(OMPC_aligned)
7070
0
                << E->getSourceRange();
7071
0
            Diag(AlignedArgs[CanonPVD]->getExprLoc(),
7072
0
                 diag::note_omp_explicit_dsa)
7073
0
                << getOpenMPClauseName(OMPC_aligned);
7074
0
            continue;
7075
0
          }
7076
0
          AlignedArgs[CanonPVD] = E;
7077
0
          QualType QTy = PVD->getType()
7078
0
                             .getNonReferenceType()
7079
0
                             .getUnqualifiedType()
7080
0
                             .getCanonicalType();
7081
0
          const Type *Ty = QTy.getTypePtrOrNull();
7082
0
          if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
7083
0
            Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
7084
0
                << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
7085
0
            Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
7086
0
          }
7087
0
          continue;
7088
0
        }
7089
0
      }
7090
0
    if (isa<CXXThisExpr>(E)) {
7091
0
      if (AlignedThis) {
7092
0
        Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
7093
0
            << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
7094
0
        Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
7095
0
            << getOpenMPClauseName(OMPC_aligned);
7096
0
      }
7097
0
      AlignedThis = E;
7098
0
      continue;
7099
0
    }
7100
0
    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7101
0
        << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7102
0
  }
7103
  // The optional parameter of the aligned clause, alignment, must be a constant
7104
  // positive integer expression. If no optional parameter is specified,
7105
  // implementation-defined default alignments for SIMD instructions on the
7106
  // target platforms are assumed.
7107
0
  SmallVector<const Expr *, 4> NewAligns;
7108
0
  for (Expr *E : Alignments) {
7109
0
    ExprResult Align;
7110
0
    if (E)
7111
0
      Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
7112
0
    NewAligns.push_back(Align.get());
7113
0
  }
7114
  // OpenMP [2.8.2, declare simd construct, Description]
7115
  // The linear clause declares one or more list items to be private to a SIMD
7116
  // lane and to have a linear relationship with respect to the iteration space
7117
  // of a loop.
7118
  // The special this pointer can be used as if was one of the arguments to the
7119
  // function in any of the linear, aligned, or uniform clauses.
7120
  // When a linear-step expression is specified in a linear clause it must be
7121
  // either a constant integer expression or an integer-typed parameter that is
7122
  // specified in a uniform clause on the directive.
7123
0
  llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
7124
0
  const bool IsUniformedThis = UniformedLinearThis != nullptr;
7125
0
  auto MI = LinModifiers.begin();
7126
0
  for (const Expr *E : Linears) {
7127
0
    auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
7128
0
    ++MI;
7129
0
    E = E->IgnoreParenImpCasts();
7130
0
    if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7131
0
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7132
0
        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7133
0
        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7134
0
            FD->getParamDecl(PVD->getFunctionScopeIndex())
7135
0
                    ->getCanonicalDecl() == CanonPVD) {
7136
          // OpenMP  [2.15.3.7, linear Clause, Restrictions]
7137
          // A list-item cannot appear in more than one linear clause.
7138
0
          if (LinearArgs.count(CanonPVD) > 0) {
7139
0
            Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7140
0
                << getOpenMPClauseName(OMPC_linear)
7141
0
                << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
7142
0
            Diag(LinearArgs[CanonPVD]->getExprLoc(),
7143
0
                 diag::note_omp_explicit_dsa)
7144
0
                << getOpenMPClauseName(OMPC_linear);
7145
0
            continue;
7146
0
          }
7147
          // Each argument can appear in at most one uniform or linear clause.
7148
0
          if (UniformedArgs.count(CanonPVD) > 0) {
7149
0
            Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7150
0
                << getOpenMPClauseName(OMPC_linear)
7151
0
                << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
7152
0
            Diag(UniformedArgs[CanonPVD]->getExprLoc(),
7153
0
                 diag::note_omp_explicit_dsa)
7154
0
                << getOpenMPClauseName(OMPC_uniform);
7155
0
            continue;
7156
0
          }
7157
0
          LinearArgs[CanonPVD] = E;
7158
0
          if (E->isValueDependent() || E->isTypeDependent() ||
7159
0
              E->isInstantiationDependent() ||
7160
0
              E->containsUnexpandedParameterPack())
7161
0
            continue;
7162
0
          (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
7163
0
                                      PVD->getOriginalType(),
7164
0
                                      /*IsDeclareSimd=*/true);
7165
0
          continue;
7166
0
        }
7167
0
      }
7168
0
    if (isa<CXXThisExpr>(E)) {
7169
0
      if (UniformedLinearThis) {
7170
0
        Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7171
0
            << getOpenMPClauseName(OMPC_linear)
7172
0
            << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
7173
0
            << E->getSourceRange();
7174
0
        Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
7175
0
            << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7176
0
                                                   : OMPC_linear);
7177
0
        continue;
7178
0
      }
7179
0
      UniformedLinearThis = E;
7180
0
      if (E->isValueDependent() || E->isTypeDependent() ||
7181
0
          E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
7182
0
        continue;
7183
0
      (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
7184
0
                                  E->getType(), /*IsDeclareSimd=*/true);
7185
0
      continue;
7186
0
    }
7187
0
    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7188
0
        << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7189
0
  }
7190
0
  Expr *Step = nullptr;
7191
0
  Expr *NewStep = nullptr;
7192
0
  SmallVector<Expr *, 4> NewSteps;
7193
0
  for (Expr *E : Steps) {
7194
    // Skip the same step expression, it was checked already.
7195
0
    if (Step == E || !E) {
7196
0
      NewSteps.push_back(E ? NewStep : nullptr);
7197
0
      continue;
7198
0
    }
7199
0
    Step = E;
7200
0
    if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7201
0
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7202
0
        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7203
0
        if (UniformedArgs.count(CanonPVD) == 0) {
7204
0
          Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
7205
0
              << Step->getSourceRange();
7206
0
        } else if (E->isValueDependent() || E->isTypeDependent() ||
7207
0
                   E->isInstantiationDependent() ||
7208
0
                   E->containsUnexpandedParameterPack() ||
7209
0
                   CanonPVD->getType()->hasIntegerRepresentation()) {
7210
0
          NewSteps.push_back(Step);
7211
0
        } else {
7212
0
          Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
7213
0
              << Step->getSourceRange();
7214
0
        }
7215
0
        continue;
7216
0
      }
7217
0
    NewStep = Step;
7218
0
    if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
7219
0
        !Step->isInstantiationDependent() &&
7220
0
        !Step->containsUnexpandedParameterPack()) {
7221
0
      NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
7222
0
                    .get();
7223
0
      if (NewStep)
7224
0
        NewStep =
7225
0
            VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
7226
0
    }
7227
0
    NewSteps.push_back(NewStep);
7228
0
  }
7229
0
  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7230
0
      Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
7231
0
      Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
7232
0
      const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
7233
0
      const_cast<Expr **>(Linears.data()), Linears.size(),
7234
0
      const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
7235
0
      NewSteps.data(), NewSteps.size(), SR);
7236
0
  ADecl->addAttr(NewAttr);
7237
0
  return DG;
7238
0
}
7239
7240
static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
7241
0
                         QualType NewType) {
7242
0
  assert(NewType->isFunctionProtoType() &&
7243
0
         "Expected function type with prototype.");
7244
0
  assert(FD->getType()->isFunctionNoProtoType() &&
7245
0
         "Expected function with type with no prototype.");
7246
0
  assert(FDWithProto->getType()->isFunctionProtoType() &&
7247
0
         "Expected function with prototype.");
7248
  // Synthesize parameters with the same types.
7249
0
  FD->setType(NewType);
7250
0
  SmallVector<ParmVarDecl *, 16> Params;
7251
0
  for (const ParmVarDecl *P : FDWithProto->parameters()) {
7252
0
    auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
7253
0
                                      SourceLocation(), nullptr, P->getType(),
7254
0
                                      /*TInfo=*/nullptr, SC_None, nullptr);
7255
0
    Param->setScopeInfo(0, Params.size());
7256
0
    Param->setImplicit();
7257
0
    Params.push_back(Param);
7258
0
  }
7259
7260
0
  FD->setParams(Params);
7261
0
}
7262
7263
0
void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
7264
0
  if (D->isInvalidDecl())
7265
0
    return;
7266
0
  FunctionDecl *FD = nullptr;
7267
0
  if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7268
0
    FD = UTemplDecl->getTemplatedDecl();
7269
0
  else
7270
0
    FD = cast<FunctionDecl>(D);
7271
0
  assert(FD && "Expected a function declaration!");
7272
7273
  // If we are instantiating templates we do *not* apply scoped assumptions but
7274
  // only global ones. We apply scoped assumption to the template definition
7275
  // though.
7276
0
  if (!inTemplateInstantiation()) {
7277
0
    for (AssumptionAttr *AA : OMPAssumeScoped)
7278
0
      FD->addAttr(AA);
7279
0
  }
7280
0
  for (AssumptionAttr *AA : OMPAssumeGlobal)
7281
0
    FD->addAttr(AA);
7282
0
}
7283
7284
Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
7285
0
    : TI(&TI), NameSuffix(TI.getMangledName()) {}
7286
7287
void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
7288
    Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
7289
0
    SmallVectorImpl<FunctionDecl *> &Bases) {
7290
0
  if (!D.getIdentifier())
7291
0
    return;
7292
7293
0
  OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7294
7295
  // Template specialization is an extension, check if we do it.
7296
0
  bool IsTemplated = !TemplateParamLists.empty();
7297
0
  if (IsTemplated &
7298
0
      !DVScope.TI->isExtensionActive(
7299
0
          llvm::omp::TraitProperty::implementation_extension_allow_templates))
7300
0
    return;
7301
7302
0
  IdentifierInfo *BaseII = D.getIdentifier();
7303
0
  LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
7304
0
                      LookupOrdinaryName);
7305
0
  LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
7306
7307
0
  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
7308
0
  QualType FType = TInfo->getType();
7309
7310
0
  bool IsConstexpr =
7311
0
      D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
7312
0
  bool IsConsteval =
7313
0
      D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
7314
7315
0
  for (auto *Candidate : Lookup) {
7316
0
    auto *CandidateDecl = Candidate->getUnderlyingDecl();
7317
0
    FunctionDecl *UDecl = nullptr;
7318
0
    if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7319
0
      auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7320
0
      if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7321
0
        UDecl = FTD->getTemplatedDecl();
7322
0
    } else if (!IsTemplated)
7323
0
      UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7324
0
    if (!UDecl)
7325
0
      continue;
7326
7327
    // Don't specialize constexpr/consteval functions with
7328
    // non-constexpr/consteval functions.
7329
0
    if (UDecl->isConstexpr() && !IsConstexpr)
7330
0
      continue;
7331
0
    if (UDecl->isConsteval() && !IsConsteval)
7332
0
      continue;
7333
7334
0
    QualType UDeclTy = UDecl->getType();
7335
0
    if (!UDeclTy->isDependentType()) {
7336
0
      QualType NewType = Context.mergeFunctionTypes(
7337
0
          FType, UDeclTy, /* OfBlockPointer */ false,
7338
0
          /* Unqualified */ false, /* AllowCXX */ true);
7339
0
      if (NewType.isNull())
7340
0
        continue;
7341
0
    }
7342
7343
    // Found a base!
7344
0
    Bases.push_back(UDecl);
7345
0
  }
7346
7347
0
  bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7348
0
      llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7349
  // If no base was found we create a declaration that we use as base.
7350
0
  if (Bases.empty() && UseImplicitBase) {
7351
0
    D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
7352
0
    Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
7353
0
    BaseD->setImplicit(true);
7354
0
    if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7355
0
      Bases.push_back(BaseTemplD->getTemplatedDecl());
7356
0
    else
7357
0
      Bases.push_back(cast<FunctionDecl>(BaseD));
7358
0
  }
7359
7360
0
  std::string MangledName;
7361
0
  MangledName += D.getIdentifier()->getName();
7362
0
  MangledName += getOpenMPVariantManglingSeparatorStr();
7363
0
  MangledName += DVScope.NameSuffix;
7364
0
  IdentifierInfo &VariantII = Context.Idents.get(MangledName);
7365
7366
0
  VariantII.setMangledOpenMPVariantName(true);
7367
0
  D.SetIdentifier(&VariantII, D.getBeginLoc());
7368
0
}
7369
7370
void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
7371
0
    Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
7372
  // Do not mark function as is used to prevent its emission if this is the
7373
  // only place where it is used.
7374
0
  EnterExpressionEvaluationContext Unevaluated(
7375
0
      *this, Sema::ExpressionEvaluationContext::Unevaluated);
7376
7377
0
  FunctionDecl *FD = nullptr;
7378
0
  if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7379
0
    FD = UTemplDecl->getTemplatedDecl();
7380
0
  else
7381
0
    FD = cast<FunctionDecl>(D);
7382
0
  auto *VariantFuncRef = DeclRefExpr::Create(
7383
0
      Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
7384
0
      /* RefersToEnclosingVariableOrCapture */ false,
7385
0
      /* NameLoc */ FD->getLocation(), FD->getType(),
7386
0
      ExprValueKind::VK_PRValue);
7387
7388
0
  OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7389
0
  auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7390
0
      Context, VariantFuncRef, DVScope.TI,
7391
0
      /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7392
0
      /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7393
0
      /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7394
0
  for (FunctionDecl *BaseFD : Bases)
7395
0
    BaseFD->addAttr(OMPDeclareVariantA);
7396
0
}
7397
7398
ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
7399
                                 SourceLocation LParenLoc,
7400
                                 MultiExprArg ArgExprs,
7401
0
                                 SourceLocation RParenLoc, Expr *ExecConfig) {
7402
  // The common case is a regular call we do not want to specialize at all. Try
7403
  // to make that case fast by bailing early.
7404
0
  CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7405
0
  if (!CE)
7406
0
    return Call;
7407
7408
0
  FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
7409
0
  if (!CalleeFnDecl)
7410
0
    return Call;
7411
7412
0
  if (LangOpts.OpenMP >= 51 && CalleeFnDecl->getIdentifier() &&
7413
0
      CalleeFnDecl->getName().starts_with_insensitive("omp_")) {
7414
    // checking for any calls inside an Order region
7415
0
    if (Scope && Scope->isOpenMPOrderClauseScope())
7416
0
      Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7417
0
  }
7418
7419
0
  if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
7420
0
    return Call;
7421
7422
0
  ASTContext &Context = getASTContext();
7423
0
  std::function<void(StringRef)> DiagUnknownTrait = [this,
7424
0
                                                     CE](StringRef ISATrait) {
7425
    // TODO Track the selector locations in a way that is accessible here to
7426
    // improve the diagnostic location.
7427
0
    Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
7428
0
        << ISATrait;
7429
0
  };
7430
0
  TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
7431
0
                          getCurFunctionDecl(), DSAStack->getConstructTraits());
7432
7433
0
  QualType CalleeFnType = CalleeFnDecl->getType();
7434
7435
0
  SmallVector<Expr *, 4> Exprs;
7436
0
  SmallVector<VariantMatchInfo, 4> VMIs;
7437
0
  while (CalleeFnDecl) {
7438
0
    for (OMPDeclareVariantAttr *A :
7439
0
         CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
7440
0
      Expr *VariantRef = A->getVariantFuncRef();
7441
7442
0
      VariantMatchInfo VMI;
7443
0
      OMPTraitInfo &TI = A->getTraitInfo();
7444
0
      TI.getAsVariantMatchInfo(Context, VMI);
7445
0
      if (!isVariantApplicableInContext(VMI, OMPCtx,
7446
0
                                        /* DeviceSetOnly */ false))
7447
0
        continue;
7448
7449
0
      VMIs.push_back(VMI);
7450
0
      Exprs.push_back(VariantRef);
7451
0
    }
7452
7453
0
    CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
7454
0
  }
7455
7456
0
  ExprResult NewCall;
7457
0
  do {
7458
0
    int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7459
0
    if (BestIdx < 0)
7460
0
      return Call;
7461
0
    Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7462
0
    Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7463
7464
0
    {
7465
      // Try to build a (member) call expression for the current best applicable
7466
      // variant expression. We allow this to fail in which case we continue
7467
      // with the next best variant expression. The fail case is part of the
7468
      // implementation defined behavior in the OpenMP standard when it talks
7469
      // about what differences in the function prototypes: "Any differences
7470
      // that the specific OpenMP context requires in the prototype of the
7471
      // variant from the base function prototype are implementation defined."
7472
      // This wording is there to allow the specialized variant to have a
7473
      // different type than the base function. This is intended and OK but if
7474
      // we cannot create a call the difference is not in the "implementation
7475
      // defined range" we allow.
7476
0
      Sema::TentativeAnalysisScope Trap(*this);
7477
7478
0
      if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7479
0
        auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7480
0
        BestExpr = MemberExpr::CreateImplicit(
7481
0
            Context, MemberCall->getImplicitObjectArgument(),
7482
0
            /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
7483
0
            MemberCall->getValueKind(), MemberCall->getObjectKind());
7484
0
      }
7485
0
      NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
7486
0
                              ExecConfig);
7487
0
      if (NewCall.isUsable()) {
7488
0
        if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7489
0
          FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7490
0
          QualType NewType = Context.mergeFunctionTypes(
7491
0
              CalleeFnType, NewCalleeFnDecl->getType(),
7492
0
              /* OfBlockPointer */ false,
7493
0
              /* Unqualified */ false, /* AllowCXX */ true);
7494
0
          if (!NewType.isNull())
7495
0
            break;
7496
          // Don't use the call if the function type was not compatible.
7497
0
          NewCall = nullptr;
7498
0
        }
7499
0
      }
7500
0
    }
7501
7502
0
    VMIs.erase(VMIs.begin() + BestIdx);
7503
0
    Exprs.erase(Exprs.begin() + BestIdx);
7504
0
  } while (!VMIs.empty());
7505
7506
0
  if (!NewCall.isUsable())
7507
0
    return Call;
7508
0
  return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7509
0
}
7510
7511
std::optional<std::pair<FunctionDecl *, Expr *>>
7512
Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
7513
                                        Expr *VariantRef, OMPTraitInfo &TI,
7514
                                        unsigned NumAppendArgs,
7515
0
                                        SourceRange SR) {
7516
0
  if (!DG || DG.get().isNull())
7517
0
    return std::nullopt;
7518
7519
0
  const int VariantId = 1;
7520
  // Must be applied only to single decl.
7521
0
  if (!DG.get().isSingleDecl()) {
7522
0
    Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7523
0
        << VariantId << SR;
7524
0
    return std::nullopt;
7525
0
  }
7526
0
  Decl *ADecl = DG.get().getSingleDecl();
7527
0
  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7528
0
    ADecl = FTD->getTemplatedDecl();
7529
7530
  // Decl must be a function.
7531
0
  auto *FD = dyn_cast<FunctionDecl>(ADecl);
7532
0
  if (!FD) {
7533
0
    Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7534
0
        << VariantId << SR;
7535
0
    return std::nullopt;
7536
0
  }
7537
7538
0
  auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7539
    // The 'target' attribute needs to be separately checked because it does
7540
    // not always signify a multiversion function declaration.
7541
0
    return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7542
0
  };
7543
  // OpenMP is not compatible with multiversion function attributes.
7544
0
  if (HasMultiVersionAttributes(FD)) {
7545
0
    Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7546
0
        << SR;
7547
0
    return std::nullopt;
7548
0
  }
7549
7550
  // Allow #pragma omp declare variant only if the function is not used.
7551
0
  if (FD->isUsed(false))
7552
0
    Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7553
0
        << FD->getLocation();
7554
7555
  // Check if the function was emitted already.
7556
0
  const FunctionDecl *Definition;
7557
0
  if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7558
0
      (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7559
0
    Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7560
0
        << FD->getLocation();
7561
7562
  // The VariantRef must point to function.
7563
0
  if (!VariantRef) {
7564
0
    Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7565
0
    return std::nullopt;
7566
0
  }
7567
7568
0
  auto ShouldDelayChecks = [](Expr *&E, bool) {
7569
0
    return E && (E->isTypeDependent() || E->isValueDependent() ||
7570
0
                 E->containsUnexpandedParameterPack() ||
7571
0
                 E->isInstantiationDependent());
7572
0
  };
7573
  // Do not check templates, wait until instantiation.
7574
0
  if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7575
0
      TI.anyScoreOrCondition(ShouldDelayChecks))
7576
0
    return std::make_pair(FD, VariantRef);
7577
7578
  // Deal with non-constant score and user condition expressions.
7579
0
  auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7580
0
                                                     bool IsScore) -> bool {
7581
0
    if (!E || E->isIntegerConstantExpr(Context))
7582
0
      return false;
7583
7584
0
    if (IsScore) {
7585
      // We warn on non-constant scores and pretend they were not present.
7586
0
      Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7587
0
          << E;
7588
0
      E = nullptr;
7589
0
    } else {
7590
      // We could replace a non-constant user condition with "false" but we
7591
      // will soon need to handle these anyway for the dynamic version of
7592
      // OpenMP context selectors.
7593
0
      Diag(E->getExprLoc(),
7594
0
           diag::err_omp_declare_variant_user_condition_not_constant)
7595
0
          << E;
7596
0
    }
7597
0
    return true;
7598
0
  };
7599
0
  if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7600
0
    return std::nullopt;
7601
7602
0
  QualType AdjustedFnType = FD->getType();
7603
0
  if (NumAppendArgs) {
7604
0
    const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7605
0
    if (!PTy) {
7606
0
      Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7607
0
          << SR;
7608
0
      return std::nullopt;
7609
0
    }
7610
    // Adjust the function type to account for an extra omp_interop_t for each
7611
    // specified in the append_args clause.
7612
0
    const TypeDecl *TD = nullptr;
7613
0
    LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7614
0
                        SR.getBegin(), Sema::LookupOrdinaryName);
7615
0
    if (LookupName(Result, getCurScope())) {
7616
0
      NamedDecl *ND = Result.getFoundDecl();
7617
0
      TD = dyn_cast_or_null<TypeDecl>(ND);
7618
0
    }
7619
0
    if (!TD) {
7620
0
      Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7621
0
      return std::nullopt;
7622
0
    }
7623
0
    QualType InteropType = Context.getTypeDeclType(TD);
7624
0
    if (PTy->isVariadic()) {
7625
0
      Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7626
0
      return std::nullopt;
7627
0
    }
7628
0
    llvm::SmallVector<QualType, 8> Params;
7629
0
    Params.append(PTy->param_type_begin(), PTy->param_type_end());
7630
0
    Params.insert(Params.end(), NumAppendArgs, InteropType);
7631
0
    AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7632
0
                                             PTy->getExtProtoInfo());
7633
0
  }
7634
7635
  // Convert VariantRef expression to the type of the original function to
7636
  // resolve possible conflicts.
7637
0
  ExprResult VariantRefCast = VariantRef;
7638
0
  if (LangOpts.CPlusPlus) {
7639
0
    QualType FnPtrType;
7640
0
    auto *Method = dyn_cast<CXXMethodDecl>(FD);
7641
0
    if (Method && !Method->isStatic()) {
7642
0
      const Type *ClassType =
7643
0
          Context.getTypeDeclType(Method->getParent()).getTypePtr();
7644
0
      FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7645
0
      ExprResult ER;
7646
0
      {
7647
        // Build adrr_of unary op to correctly handle type checks for member
7648
        // functions.
7649
0
        Sema::TentativeAnalysisScope Trap(*this);
7650
0
        ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7651
0
                                  VariantRef);
7652
0
      }
7653
0
      if (!ER.isUsable()) {
7654
0
        Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7655
0
            << VariantId << VariantRef->getSourceRange();
7656
0
        return std::nullopt;
7657
0
      }
7658
0
      VariantRef = ER.get();
7659
0
    } else {
7660
0
      FnPtrType = Context.getPointerType(AdjustedFnType);
7661
0
    }
7662
0
    QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7663
0
    if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7664
0
      ImplicitConversionSequence ICS = TryImplicitConversion(
7665
0
          VariantRef, FnPtrType.getUnqualifiedType(),
7666
0
          /*SuppressUserConversions=*/false, AllowedExplicit::None,
7667
0
          /*InOverloadResolution=*/false,
7668
0
          /*CStyle=*/false,
7669
0
          /*AllowObjCWritebackConversion=*/false);
7670
0
      if (ICS.isFailure()) {
7671
0
        Diag(VariantRef->getExprLoc(),
7672
0
             diag::err_omp_declare_variant_incompat_types)
7673
0
            << VariantRef->getType()
7674
0
            << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7675
0
            << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7676
0
        return std::nullopt;
7677
0
      }
7678
0
      VariantRefCast = PerformImplicitConversion(
7679
0
          VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7680
0
      if (!VariantRefCast.isUsable())
7681
0
        return std::nullopt;
7682
0
    }
7683
    // Drop previously built artificial addr_of unary op for member functions.
7684
0
    if (Method && !Method->isStatic()) {
7685
0
      Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7686
0
      if (auto *UO = dyn_cast<UnaryOperator>(
7687
0
              PossibleAddrOfVariantRef->IgnoreImplicit()))
7688
0
        VariantRefCast = UO->getSubExpr();
7689
0
    }
7690
0
  }
7691
7692
0
  ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7693
0
  if (!ER.isUsable() ||
7694
0
      !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7695
0
    Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7696
0
        << VariantId << VariantRef->getSourceRange();
7697
0
    return std::nullopt;
7698
0
  }
7699
7700
  // The VariantRef must point to function.
7701
0
  auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7702
0
  if (!DRE) {
7703
0
    Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7704
0
        << VariantId << VariantRef->getSourceRange();
7705
0
    return std::nullopt;
7706
0
  }
7707
0
  auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7708
0
  if (!NewFD) {
7709
0
    Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7710
0
        << VariantId << VariantRef->getSourceRange();
7711
0
    return std::nullopt;
7712
0
  }
7713
7714
0
  if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7715
0
    Diag(VariantRef->getExprLoc(),
7716
0
         diag::err_omp_declare_variant_same_base_function)
7717
0
        << VariantRef->getSourceRange();
7718
0
    return std::nullopt;
7719
0
  }
7720
7721
  // Check if function types are compatible in C.
7722
0
  if (!LangOpts.CPlusPlus) {
7723
0
    QualType NewType =
7724
0
        Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7725
0
    if (NewType.isNull()) {
7726
0
      Diag(VariantRef->getExprLoc(),
7727
0
           diag::err_omp_declare_variant_incompat_types)
7728
0
          << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7729
0
          << VariantRef->getSourceRange();
7730
0
      return std::nullopt;
7731
0
    }
7732
0
    if (NewType->isFunctionProtoType()) {
7733
0
      if (FD->getType()->isFunctionNoProtoType())
7734
0
        setPrototype(*this, FD, NewFD, NewType);
7735
0
      else if (NewFD->getType()->isFunctionNoProtoType())
7736
0
        setPrototype(*this, NewFD, FD, NewType);
7737
0
    }
7738
0
  }
7739
7740
  // Check if variant function is not marked with declare variant directive.
7741
0
  if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7742
0
    Diag(VariantRef->getExprLoc(),
7743
0
         diag::warn_omp_declare_variant_marked_as_declare_variant)
7744
0
        << VariantRef->getSourceRange();
7745
0
    SourceRange SR =
7746
0
        NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7747
0
    Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7748
0
    return std::nullopt;
7749
0
  }
7750
7751
0
  enum DoesntSupport {
7752
0
    VirtFuncs = 1,
7753
0
    Constructors = 3,
7754
0
    Destructors = 4,
7755
0
    DeletedFuncs = 5,
7756
0
    DefaultedFuncs = 6,
7757
0
    ConstexprFuncs = 7,
7758
0
    ConstevalFuncs = 8,
7759
0
  };
7760
0
  if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7761
0
    if (CXXFD->isVirtual()) {
7762
0
      Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7763
0
          << VirtFuncs;
7764
0
      return std::nullopt;
7765
0
    }
7766
7767
0
    if (isa<CXXConstructorDecl>(FD)) {
7768
0
      Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7769
0
          << Constructors;
7770
0
      return std::nullopt;
7771
0
    }
7772
7773
0
    if (isa<CXXDestructorDecl>(FD)) {
7774
0
      Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7775
0
          << Destructors;
7776
0
      return std::nullopt;
7777
0
    }
7778
0
  }
7779
7780
0
  if (FD->isDeleted()) {
7781
0
    Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7782
0
        << DeletedFuncs;
7783
0
    return std::nullopt;
7784
0
  }
7785
7786
0
  if (FD->isDefaulted()) {
7787
0
    Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7788
0
        << DefaultedFuncs;
7789
0
    return std::nullopt;
7790
0
  }
7791
7792
0
  if (FD->isConstexpr()) {
7793
0
    Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7794
0
        << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7795
0
    return std::nullopt;
7796
0
  }
7797
7798
  // Check general compatibility.
7799
0
  if (areMultiversionVariantFunctionsCompatible(
7800
0
          FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7801
0
          PartialDiagnosticAt(SourceLocation(),
7802
0
                              PartialDiagnostic::NullDiagnostic()),
7803
0
          PartialDiagnosticAt(
7804
0
              VariantRef->getExprLoc(),
7805
0
              PDiag(diag::err_omp_declare_variant_doesnt_support)),
7806
0
          PartialDiagnosticAt(VariantRef->getExprLoc(),
7807
0
                              PDiag(diag::err_omp_declare_variant_diff)
7808
0
                                  << FD->getLocation()),
7809
0
          /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7810
0
          /*CLinkageMayDiffer=*/true))
7811
0
    return std::nullopt;
7812
0
  return std::make_pair(FD, cast<Expr>(DRE));
7813
0
}
7814
7815
void Sema::ActOnOpenMPDeclareVariantDirective(
7816
    FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7817
    ArrayRef<Expr *> AdjustArgsNothing,
7818
    ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7819
    ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
7820
0
    SourceLocation AppendArgsLoc, SourceRange SR) {
7821
7822
  // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7823
  // An adjust_args clause or append_args clause can only be specified if the
7824
  // dispatch selector of the construct selector set appears in the match
7825
  // clause.
7826
7827
0
  SmallVector<Expr *, 8> AllAdjustArgs;
7828
0
  llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7829
0
  llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7830
7831
0
  if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7832
0
    VariantMatchInfo VMI;
7833
0
    TI.getAsVariantMatchInfo(Context, VMI);
7834
0
    if (!llvm::is_contained(
7835
0
            VMI.ConstructTraits,
7836
0
            llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7837
0
      if (!AllAdjustArgs.empty())
7838
0
        Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7839
0
            << getOpenMPClauseName(OMPC_adjust_args);
7840
0
      if (!AppendArgs.empty())
7841
0
        Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7842
0
            << getOpenMPClauseName(OMPC_append_args);
7843
0
      return;
7844
0
    }
7845
0
  }
7846
7847
  // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7848
  // Each argument can only appear in a single adjust_args clause for each
7849
  // declare variant directive.
7850
0
  llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7851
7852
0
  for (Expr *E : AllAdjustArgs) {
7853
0
    E = E->IgnoreParenImpCasts();
7854
0
    if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7855
0
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7856
0
        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7857
0
        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7858
0
            FD->getParamDecl(PVD->getFunctionScopeIndex())
7859
0
                    ->getCanonicalDecl() == CanonPVD) {
7860
          // It's a parameter of the function, check duplicates.
7861
0
          if (!AdjustVars.insert(CanonPVD).second) {
7862
0
            Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7863
0
                << PVD;
7864
0
            return;
7865
0
          }
7866
0
          continue;
7867
0
        }
7868
0
      }
7869
0
    }
7870
    // Anything that is not a function parameter is an error.
7871
0
    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7872
0
    return;
7873
0
  }
7874
7875
0
  auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7876
0
      Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7877
0
      AdjustArgsNothing.size(),
7878
0
      const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7879
0
      AdjustArgsNeedDevicePtr.size(),
7880
0
      const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR);
7881
0
  FD->addAttr(NewAttr);
7882
0
}
7883
7884
StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7885
                                              Stmt *AStmt,
7886
                                              SourceLocation StartLoc,
7887
0
                                              SourceLocation EndLoc) {
7888
0
  if (!AStmt)
7889
0
    return StmtError();
7890
7891
0
  auto *CS = cast<CapturedStmt>(AStmt);
7892
  // 1.2.2 OpenMP Language Terminology
7893
  // Structured block - An executable statement with a single entry at the
7894
  // top and a single exit at the bottom.
7895
  // The point of exit cannot be a branch out of the structured block.
7896
  // longjmp() and throw() must not violate the entry/exit criteria.
7897
0
  CS->getCapturedDecl()->setNothrow();
7898
7899
0
  setFunctionHasBranchProtectedScope();
7900
7901
0
  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7902
0
                                      DSAStack->getTaskgroupReductionRef(),
7903
0
                                      DSAStack->isCancelRegion());
7904
0
}
7905
7906
namespace {
7907
/// Iteration space of a single for loop.
7908
struct LoopIterationSpace final {
7909
  /// True if the condition operator is the strict compare operator (<, > or
7910
  /// !=).
7911
  bool IsStrictCompare = false;
7912
  /// Condition of the loop.
7913
  Expr *PreCond = nullptr;
7914
  /// This expression calculates the number of iterations in the loop.
7915
  /// It is always possible to calculate it before starting the loop.
7916
  Expr *NumIterations = nullptr;
7917
  /// The loop counter variable.
7918
  Expr *CounterVar = nullptr;
7919
  /// Private loop counter variable.
7920
  Expr *PrivateCounterVar = nullptr;
7921
  /// This is initializer for the initial value of #CounterVar.
7922
  Expr *CounterInit = nullptr;
7923
  /// This is step for the #CounterVar used to generate its update:
7924
  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7925
  Expr *CounterStep = nullptr;
7926
  /// Should step be subtracted?
7927
  bool Subtract = false;
7928
  /// Source range of the loop init.
7929
  SourceRange InitSrcRange;
7930
  /// Source range of the loop condition.
7931
  SourceRange CondSrcRange;
7932
  /// Source range of the loop increment.
7933
  SourceRange IncSrcRange;
7934
  /// Minimum value that can have the loop control variable. Used to support
7935
  /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7936
  /// since only such variables can be used in non-loop invariant expressions.
7937
  Expr *MinValue = nullptr;
7938
  /// Maximum value that can have the loop control variable. Used to support
7939
  /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7940
  /// since only such variables can be used in non-loop invariant expressions.
7941
  Expr *MaxValue = nullptr;
7942
  /// true, if the lower bound depends on the outer loop control var.
7943
  bool IsNonRectangularLB = false;
7944
  /// true, if the upper bound depends on the outer loop control var.
7945
  bool IsNonRectangularUB = false;
7946
  /// Index of the loop this loop depends on and forms non-rectangular loop
7947
  /// nest.
7948
  unsigned LoopDependentIdx = 0;
7949
  /// Final condition for the non-rectangular loop nest support. It is used to
7950
  /// check that the number of iterations for this particular counter must be
7951
  /// finished.
7952
  Expr *FinalCondition = nullptr;
7953
};
7954
7955
/// Helper class for checking canonical form of the OpenMP loops and
7956
/// extracting iteration space of each loop in the loop nest, that will be used
7957
/// for IR generation.
7958
class OpenMPIterationSpaceChecker {
7959
  /// Reference to Sema.
7960
  Sema &SemaRef;
7961
  /// Does the loop associated directive support non-rectangular loops?
7962
  bool SupportsNonRectangular;
7963
  /// Data-sharing stack.
7964
  DSAStackTy &Stack;
7965
  /// A location for diagnostics (when there is no some better location).
7966
  SourceLocation DefaultLoc;
7967
  /// A location for diagnostics (when increment is not compatible).
7968
  SourceLocation ConditionLoc;
7969
  /// A source location for referring to loop init later.
7970
  SourceRange InitSrcRange;
7971
  /// A source location for referring to condition later.
7972
  SourceRange ConditionSrcRange;
7973
  /// A source location for referring to increment later.
7974
  SourceRange IncrementSrcRange;
7975
  /// Loop variable.
7976
  ValueDecl *LCDecl = nullptr;
7977
  /// Reference to loop variable.
7978
  Expr *LCRef = nullptr;
7979
  /// Lower bound (initializer for the var).
7980
  Expr *LB = nullptr;
7981
  /// Upper bound.
7982
  Expr *UB = nullptr;
7983
  /// Loop step (increment).
7984
  Expr *Step = nullptr;
7985
  /// This flag is true when condition is one of:
7986
  ///   Var <  UB
7987
  ///   Var <= UB
7988
  ///   UB  >  Var
7989
  ///   UB  >= Var
7990
  /// This will have no value when the condition is !=
7991
  std::optional<bool> TestIsLessOp;
7992
  /// This flag is true when condition is strict ( < or > ).
7993
  bool TestIsStrictOp = false;
7994
  /// This flag is true when step is subtracted on each iteration.
7995
  bool SubtractStep = false;
7996
  /// The outer loop counter this loop depends on (if any).
7997
  const ValueDecl *DepDecl = nullptr;
7998
  /// Contains number of loop (starts from 1) on which loop counter init
7999
  /// expression of this loop depends on.
8000
  std::optional<unsigned> InitDependOnLC;
8001
  /// Contains number of loop (starts from 1) on which loop counter condition
8002
  /// expression of this loop depends on.
8003
  std::optional<unsigned> CondDependOnLC;
8004
  /// Checks if the provide statement depends on the loop counter.
8005
  std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S,
8006
                                                  bool IsInitializer);
8007
  /// Original condition required for checking of the exit condition for
8008
  /// non-rectangular loop.
8009
  Expr *Condition = nullptr;
8010
8011
public:
8012
  OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
8013
                              DSAStackTy &Stack, SourceLocation DefaultLoc)
8014
      : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
8015
0
        Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
8016
  /// Check init-expr for canonical loop form and save loop counter
8017
  /// variable - #Var and its initialization value - #LB.
8018
  bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
8019
  /// Check test-expr for canonical form, save upper-bound (#UB), flags
8020
  /// for less/greater and for strict/non-strict comparison.
8021
  bool checkAndSetCond(Expr *S);
8022
  /// Check incr-expr for canonical loop form and return true if it
8023
  /// does not conform, otherwise save loop step (#Step).
8024
  bool checkAndSetInc(Expr *S);
8025
  /// Return the loop counter variable.
8026
0
  ValueDecl *getLoopDecl() const { return LCDecl; }
8027
  /// Return the reference expression to loop counter variable.
8028
0
  Expr *getLoopDeclRefExpr() const { return LCRef; }
8029
  /// Source range of the loop init.
8030
0
  SourceRange getInitSrcRange() const { return InitSrcRange; }
8031
  /// Source range of the loop condition.
8032
0
  SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
8033
  /// Source range of the loop increment.
8034
0
  SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
8035
  /// True if the step should be subtracted.
8036
0
  bool shouldSubtractStep() const { return SubtractStep; }
8037
  /// True, if the compare operator is strict (<, > or !=).
8038
0
  bool isStrictTestOp() const { return TestIsStrictOp; }
8039
  /// Build the expression to calculate the number of iterations.
8040
  Expr *buildNumIterations(
8041
      Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8042
      llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8043
  /// Build the precondition expression for the loops.
8044
  Expr *
8045
  buildPreCond(Scope *S, Expr *Cond,
8046
               llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8047
  /// Build reference expression to the counter be used for codegen.
8048
  DeclRefExpr *
8049
  buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8050
                  DSAStackTy &DSA) const;
8051
  /// Build reference expression to the private counter be used for
8052
  /// codegen.
8053
  Expr *buildPrivateCounterVar() const;
8054
  /// Build initialization of the counter be used for codegen.
8055
  Expr *buildCounterInit() const;
8056
  /// Build step of the counter be used for codegen.
8057
  Expr *buildCounterStep() const;
8058
  /// Build loop data with counter value for depend clauses in ordered
8059
  /// directives.
8060
  Expr *
8061
  buildOrderedLoopData(Scope *S, Expr *Counter,
8062
                       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8063
                       SourceLocation Loc, Expr *Inc = nullptr,
8064
                       OverloadedOperatorKind OOK = OO_Amp);
8065
  /// Builds the minimum value for the loop counter.
8066
  std::pair<Expr *, Expr *> buildMinMaxValues(
8067
      Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8068
  /// Builds final condition for the non-rectangular loops.
8069
  Expr *buildFinalCondition(Scope *S) const;
8070
  /// Return true if any expression is dependent.
8071
  bool dependent() const;
8072
  /// Returns true if the initializer forms non-rectangular loop.
8073
0
  bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); }
8074
  /// Returns true if the condition forms non-rectangular loop.
8075
0
  bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); }
8076
  /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
8077
0
  unsigned getLoopDependentIdx() const {
8078
0
    return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
8079
0
  }
8080
8081
private:
8082
  /// Check the right-hand side of an assignment in the increment
8083
  /// expression.
8084
  bool checkAndSetIncRHS(Expr *RHS);
8085
  /// Helper to set loop counter variable and its initializer.
8086
  bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
8087
                      bool EmitDiags);
8088
  /// Helper to set upper bound.
8089
  bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp,
8090
             SourceRange SR, SourceLocation SL);
8091
  /// Helper to set loop increment.
8092
  bool setStep(Expr *NewStep, bool Subtract);
8093
};
8094
8095
0
bool OpenMPIterationSpaceChecker::dependent() const {
8096
0
  if (!LCDecl) {
8097
0
    assert(!LB && !UB && !Step);
8098
0
    return false;
8099
0
  }
8100
0
  return LCDecl->getType()->isDependentType() ||
8101
0
         (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
8102
0
         (Step && Step->isValueDependent());
8103
0
}
8104
8105
bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
8106
                                                 Expr *NewLCRefExpr,
8107
0
                                                 Expr *NewLB, bool EmitDiags) {
8108
  // State consistency checking to ensure correct usage.
8109
0
  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
8110
0
         UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
8111
0
  if (!NewLCDecl || !NewLB || NewLB->containsErrors())
8112
0
    return true;
8113
0
  LCDecl = getCanonicalDecl(NewLCDecl);
8114
0
  LCRef = NewLCRefExpr;
8115
0
  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
8116
0
    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8117
0
      if ((Ctor->isCopyOrMoveConstructor() ||
8118
0
           Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8119
0
          CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8120
0
        NewLB = CE->getArg(0)->IgnoreParenImpCasts();
8121
0
  LB = NewLB;
8122
0
  if (EmitDiags)
8123
0
    InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
8124
0
  return false;
8125
0
}
8126
8127
bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp,
8128
                                        bool StrictOp, SourceRange SR,
8129
0
                                        SourceLocation SL) {
8130
  // State consistency checking to ensure correct usage.
8131
0
  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
8132
0
         Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
8133
0
  if (!NewUB || NewUB->containsErrors())
8134
0
    return true;
8135
0
  UB = NewUB;
8136
0
  if (LessOp)
8137
0
    TestIsLessOp = LessOp;
8138
0
  TestIsStrictOp = StrictOp;
8139
0
  ConditionSrcRange = SR;
8140
0
  ConditionLoc = SL;
8141
0
  CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
8142
0
  return false;
8143
0
}
8144
8145
0
bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
8146
  // State consistency checking to ensure correct usage.
8147
0
  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
8148
0
  if (!NewStep || NewStep->containsErrors())
8149
0
    return true;
8150
0
  if (!NewStep->isValueDependent()) {
8151
    // Check that the step is integer expression.
8152
0
    SourceLocation StepLoc = NewStep->getBeginLoc();
8153
0
    ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
8154
0
        StepLoc, getExprAsWritten(NewStep));
8155
0
    if (Val.isInvalid())
8156
0
      return true;
8157
0
    NewStep = Val.get();
8158
8159
    // OpenMP [2.6, Canonical Loop Form, Restrictions]
8160
    //  If test-expr is of form var relational-op b and relational-op is < or
8161
    //  <= then incr-expr must cause var to increase on each iteration of the
8162
    //  loop. If test-expr is of form var relational-op b and relational-op is
8163
    //  > or >= then incr-expr must cause var to decrease on each iteration of
8164
    //  the loop.
8165
    //  If test-expr is of form b relational-op var and relational-op is < or
8166
    //  <= then incr-expr must cause var to decrease on each iteration of the
8167
    //  loop. If test-expr is of form b relational-op var and relational-op is
8168
    //  > or >= then incr-expr must cause var to increase on each iteration of
8169
    //  the loop.
8170
0
    std::optional<llvm::APSInt> Result =
8171
0
        NewStep->getIntegerConstantExpr(SemaRef.Context);
8172
0
    bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
8173
0
    bool IsConstNeg =
8174
0
        Result && Result->isSigned() && (Subtract != Result->isNegative());
8175
0
    bool IsConstPos =
8176
0
        Result && Result->isSigned() && (Subtract == Result->isNegative());
8177
0
    bool IsConstZero = Result && !Result->getBoolValue();
8178
8179
    // != with increment is treated as <; != with decrement is treated as >
8180
0
    if (!TestIsLessOp)
8181
0
      TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
8182
0
    if (UB && (IsConstZero ||
8183
0
               (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
8184
0
                              : (IsConstPos || (IsUnsigned && !Subtract))))) {
8185
0
      SemaRef.Diag(NewStep->getExprLoc(),
8186
0
                   diag::err_omp_loop_incr_not_compatible)
8187
0
          << LCDecl << *TestIsLessOp << NewStep->getSourceRange();
8188
0
      SemaRef.Diag(ConditionLoc,
8189
0
                   diag::note_omp_loop_cond_requres_compatible_incr)
8190
0
          << *TestIsLessOp << ConditionSrcRange;
8191
0
      return true;
8192
0
    }
8193
0
    if (*TestIsLessOp == Subtract) {
8194
0
      NewStep =
8195
0
          SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
8196
0
              .get();
8197
0
      Subtract = !Subtract;
8198
0
    }
8199
0
  }
8200
8201
0
  Step = NewStep;
8202
0
  SubtractStep = Subtract;
8203
0
  return false;
8204
0
}
8205
8206
namespace {
8207
/// Checker for the non-rectangular loops. Checks if the initializer or
8208
/// condition expression references loop counter variable.
8209
class LoopCounterRefChecker final
8210
    : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
8211
  Sema &SemaRef;
8212
  DSAStackTy &Stack;
8213
  const ValueDecl *CurLCDecl = nullptr;
8214
  const ValueDecl *DepDecl = nullptr;
8215
  const ValueDecl *PrevDepDecl = nullptr;
8216
  bool IsInitializer = true;
8217
  bool SupportsNonRectangular;
8218
  unsigned BaseLoopId = 0;
8219
0
  bool checkDecl(const Expr *E, const ValueDecl *VD) {
8220
0
    if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
8221
0
      SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8222
0
          << (IsInitializer ? 0 : 1);
8223
0
      return false;
8224
0
    }
8225
0
    const auto &&Data = Stack.isLoopControlVariable(VD);
8226
    // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
8227
    // The type of the loop iterator on which we depend may not have a random
8228
    // access iterator type.
8229
0
    if (Data.first && VD->getType()->isRecordType()) {
8230
0
      SmallString<128> Name;
8231
0
      llvm::raw_svector_ostream OS(Name);
8232
0
      VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8233
0
                               /*Qualified=*/true);
8234
0
      SemaRef.Diag(E->getExprLoc(),
8235
0
                   diag::err_omp_wrong_dependency_iterator_type)
8236
0
          << OS.str();
8237
0
      SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
8238
0
      return false;
8239
0
    }
8240
0
    if (Data.first && !SupportsNonRectangular) {
8241
0
      SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
8242
0
      return false;
8243
0
    }
8244
0
    if (Data.first &&
8245
0
        (DepDecl || (PrevDepDecl &&
8246
0
                     getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
8247
0
      if (!DepDecl && PrevDepDecl)
8248
0
        DepDecl = PrevDepDecl;
8249
0
      SmallString<128> Name;
8250
0
      llvm::raw_svector_ostream OS(Name);
8251
0
      DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8252
0
                                    /*Qualified=*/true);
8253
0
      SemaRef.Diag(E->getExprLoc(),
8254
0
                   diag::err_omp_invariant_or_linear_dependency)
8255
0
          << OS.str();
8256
0
      return false;
8257
0
    }
8258
0
    if (Data.first) {
8259
0
      DepDecl = VD;
8260
0
      BaseLoopId = Data.first;
8261
0
    }
8262
0
    return Data.first;
8263
0
  }
8264
8265
public:
8266
0
  bool VisitDeclRefExpr(const DeclRefExpr *E) {
8267
0
    const ValueDecl *VD = E->getDecl();
8268
0
    if (isa<VarDecl>(VD))
8269
0
      return checkDecl(E, VD);
8270
0
    return false;
8271
0
  }
8272
0
  bool VisitMemberExpr(const MemberExpr *E) {
8273
0
    if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
8274
0
      const ValueDecl *VD = E->getMemberDecl();
8275
0
      if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8276
0
        return checkDecl(E, VD);
8277
0
    }
8278
0
    return false;
8279
0
  }
8280
0
  bool VisitStmt(const Stmt *S) {
8281
0
    bool Res = false;
8282
0
    for (const Stmt *Child : S->children())
8283
0
      Res = (Child && Visit(Child)) || Res;
8284
0
    return Res;
8285
0
  }
8286
  explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
8287
                                 const ValueDecl *CurLCDecl, bool IsInitializer,
8288
                                 const ValueDecl *PrevDepDecl = nullptr,
8289
                                 bool SupportsNonRectangular = true)
8290
      : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8291
        PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8292
0
        SupportsNonRectangular(SupportsNonRectangular) {}
8293
0
  unsigned getBaseLoopId() const {
8294
0
    assert(CurLCDecl && "Expected loop dependency.");
8295
0
    return BaseLoopId;
8296
0
  }
8297
0
  const ValueDecl *getDepDecl() const {
8298
0
    assert(CurLCDecl && "Expected loop dependency.");
8299
0
    return DepDecl;
8300
0
  }
8301
};
8302
} // namespace
8303
8304
std::optional<unsigned>
8305
OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
8306
0
                                                     bool IsInitializer) {
8307
  // Check for the non-rectangular loops.
8308
0
  LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8309
0
                                        DepDecl, SupportsNonRectangular);
8310
0
  if (LoopStmtChecker.Visit(S)) {
8311
0
    DepDecl = LoopStmtChecker.getDepDecl();
8312
0
    return LoopStmtChecker.getBaseLoopId();
8313
0
  }
8314
0
  return std::nullopt;
8315
0
}
8316
8317
0
bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
8318
  // Check init-expr for canonical loop form and save loop counter
8319
  // variable - #Var and its initialization value - #LB.
8320
  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8321
  //   var = lb
8322
  //   integer-type var = lb
8323
  //   random-access-iterator-type var = lb
8324
  //   pointer-type var = lb
8325
  //
8326
0
  if (!S) {
8327
0
    if (EmitDiags) {
8328
0
      SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8329
0
    }
8330
0
    return true;
8331
0
  }
8332
0
  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8333
0
    if (!ExprTemp->cleanupsHaveSideEffects())
8334
0
      S = ExprTemp->getSubExpr();
8335
8336
0
  InitSrcRange = S->getSourceRange();
8337
0
  if (Expr *E = dyn_cast<Expr>(S))
8338
0
    S = E->IgnoreParens();
8339
0
  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8340
0
    if (BO->getOpcode() == BO_Assign) {
8341
0
      Expr *LHS = BO->getLHS()->IgnoreParens();
8342
0
      if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8343
0
        if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8344
0
          if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8345
0
            return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8346
0
                                  EmitDiags);
8347
0
        return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8348
0
      }
8349
0
      if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8350
0
        if (ME->isArrow() &&
8351
0
            isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8352
0
          return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8353
0
                                EmitDiags);
8354
0
      }
8355
0
    }
8356
0
  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
8357
0
    if (DS->isSingleDecl()) {
8358
0
      if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8359
0
        if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8360
          // Accept non-canonical init form here but emit ext. warning.
8361
0
          if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
8362
0
            SemaRef.Diag(S->getBeginLoc(),
8363
0
                         diag::ext_omp_loop_not_canonical_init)
8364
0
                << S->getSourceRange();
8365
0
          return setLCDeclAndLB(
8366
0
              Var,
8367
0
              buildDeclRefExpr(SemaRef, Var,
8368
0
                               Var->getType().getNonReferenceType(),
8369
0
                               DS->getBeginLoc()),
8370
0
              Var->getInit(), EmitDiags);
8371
0
        }
8372
0
      }
8373
0
    }
8374
0
  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8375
0
    if (CE->getOperator() == OO_Equal) {
8376
0
      Expr *LHS = CE->getArg(0);
8377
0
      if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8378
0
        if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8379
0
          if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8380
0
            return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8381
0
                                  EmitDiags);
8382
0
        return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8383
0
      }
8384
0
      if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8385
0
        if (ME->isArrow() &&
8386
0
            isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8387
0
          return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8388
0
                                EmitDiags);
8389
0
      }
8390
0
    }
8391
0
  }
8392
8393
0
  if (dependent() || SemaRef.CurContext->isDependentContext())
8394
0
    return false;
8395
0
  if (EmitDiags) {
8396
0
    SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8397
0
        << S->getSourceRange();
8398
0
  }
8399
0
  return true;
8400
0
}
8401
8402
/// Ignore parenthesizes, implicit casts, copy constructor and return the
8403
/// variable (which may be the loop variable) if possible.
8404
0
static const ValueDecl *getInitLCDecl(const Expr *E) {
8405
0
  if (!E)
8406
0
    return nullptr;
8407
0
  E = getExprAsWritten(E);
8408
0
  if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8409
0
    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8410
0
      if ((Ctor->isCopyOrMoveConstructor() ||
8411
0
           Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8412
0
          CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8413
0
        E = CE->getArg(0)->IgnoreParenImpCasts();
8414
0
  if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8415
0
    if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8416
0
      return getCanonicalDecl(VD);
8417
0
  }
8418
0
  if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8419
0
    if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8420
0
      return getCanonicalDecl(ME->getMemberDecl());
8421
0
  return nullptr;
8422
0
}
8423
8424
0
bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
8425
  // Check test-expr for canonical form, save upper-bound UB, flags for
8426
  // less/greater and for strict/non-strict comparison.
8427
  // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8428
  //   var relational-op b
8429
  //   b relational-op var
8430
  //
8431
0
  bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8432
0
  if (!S) {
8433
0
    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8434
0
        << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8435
0
    return true;
8436
0
  }
8437
0
  Condition = S;
8438
0
  S = getExprAsWritten(S);
8439
0
  SourceLocation CondLoc = S->getBeginLoc();
8440
0
  auto &&CheckAndSetCond =
8441
0
      [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS,
8442
0
                                  const Expr *RHS, SourceRange SR,
8443
0
                                  SourceLocation OpLoc) -> std::optional<bool> {
8444
0
    if (BinaryOperator::isRelationalOp(Opcode)) {
8445
0
      if (getInitLCDecl(LHS) == LCDecl)
8446
0
        return setUB(const_cast<Expr *>(RHS),
8447
0
                     (Opcode == BO_LT || Opcode == BO_LE),
8448
0
                     (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8449
0
      if (getInitLCDecl(RHS) == LCDecl)
8450
0
        return setUB(const_cast<Expr *>(LHS),
8451
0
                     (Opcode == BO_GT || Opcode == BO_GE),
8452
0
                     (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8453
0
    } else if (IneqCondIsCanonical && Opcode == BO_NE) {
8454
0
      return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8455
0
                   /*LessOp=*/std::nullopt,
8456
0
                   /*StrictOp=*/true, SR, OpLoc);
8457
0
    }
8458
0
    return std::nullopt;
8459
0
  };
8460
0
  std::optional<bool> Res;
8461
0
  if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8462
0
    CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
8463
0
    Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
8464
0
                          RBO->getOperatorLoc());
8465
0
  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8466
0
    Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8467
0
                          BO->getSourceRange(), BO->getOperatorLoc());
8468
0
  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8469
0
    if (CE->getNumArgs() == 2) {
8470
0
      Res = CheckAndSetCond(
8471
0
          BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
8472
0
          CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8473
0
    }
8474
0
  }
8475
0
  if (Res)
8476
0
    return *Res;
8477
0
  if (dependent() || SemaRef.CurContext->isDependentContext())
8478
0
    return false;
8479
0
  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8480
0
      << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8481
0
  return true;
8482
0
}
8483
8484
0
bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8485
  // RHS of canonical loop form increment can be:
8486
  //   var + incr
8487
  //   incr + var
8488
  //   var - incr
8489
  //
8490
0
  RHS = RHS->IgnoreParenImpCasts();
8491
0
  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8492
0
    if (BO->isAdditiveOp()) {
8493
0
      bool IsAdd = BO->getOpcode() == BO_Add;
8494
0
      if (getInitLCDecl(BO->getLHS()) == LCDecl)
8495
0
        return setStep(BO->getRHS(), !IsAdd);
8496
0
      if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8497
0
        return setStep(BO->getLHS(), /*Subtract=*/false);
8498
0
    }
8499
0
  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8500
0
    bool IsAdd = CE->getOperator() == OO_Plus;
8501
0
    if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8502
0
      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8503
0
        return setStep(CE->getArg(1), !IsAdd);
8504
0
      if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8505
0
        return setStep(CE->getArg(0), /*Subtract=*/false);
8506
0
    }
8507
0
  }
8508
0
  if (dependent() || SemaRef.CurContext->isDependentContext())
8509
0
    return false;
8510
0
  SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8511
0
      << RHS->getSourceRange() << LCDecl;
8512
0
  return true;
8513
0
}
8514
8515
0
bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8516
  // Check incr-expr for canonical loop form and return true if it
8517
  // does not conform.
8518
  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8519
  //   ++var
8520
  //   var++
8521
  //   --var
8522
  //   var--
8523
  //   var += incr
8524
  //   var -= incr
8525
  //   var = var + incr
8526
  //   var = incr + var
8527
  //   var = var - incr
8528
  //
8529
0
  if (!S) {
8530
0
    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8531
0
    return true;
8532
0
  }
8533
0
  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8534
0
    if (!ExprTemp->cleanupsHaveSideEffects())
8535
0
      S = ExprTemp->getSubExpr();
8536
8537
0
  IncrementSrcRange = S->getSourceRange();
8538
0
  S = S->IgnoreParens();
8539
0
  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8540
0
    if (UO->isIncrementDecrementOp() &&
8541
0
        getInitLCDecl(UO->getSubExpr()) == LCDecl)
8542
0
      return setStep(SemaRef
8543
0
                         .ActOnIntegerConstant(UO->getBeginLoc(),
8544
0
                                               (UO->isDecrementOp() ? -1 : 1))
8545
0
                         .get(),
8546
0
                     /*Subtract=*/false);
8547
0
  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8548
0
    switch (BO->getOpcode()) {
8549
0
    case BO_AddAssign:
8550
0
    case BO_SubAssign:
8551
0
      if (getInitLCDecl(BO->getLHS()) == LCDecl)
8552
0
        return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8553
0
      break;
8554
0
    case BO_Assign:
8555
0
      if (getInitLCDecl(BO->getLHS()) == LCDecl)
8556
0
        return checkAndSetIncRHS(BO->getRHS());
8557
0
      break;
8558
0
    default:
8559
0
      break;
8560
0
    }
8561
0
  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8562
0
    switch (CE->getOperator()) {
8563
0
    case OO_PlusPlus:
8564
0
    case OO_MinusMinus:
8565
0
      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8566
0
        return setStep(SemaRef
8567
0
                           .ActOnIntegerConstant(
8568
0
                               CE->getBeginLoc(),
8569
0
                               ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8570
0
                           .get(),
8571
0
                       /*Subtract=*/false);
8572
0
      break;
8573
0
    case OO_PlusEqual:
8574
0
    case OO_MinusEqual:
8575
0
      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8576
0
        return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8577
0
      break;
8578
0
    case OO_Equal:
8579
0
      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8580
0
        return checkAndSetIncRHS(CE->getArg(1));
8581
0
      break;
8582
0
    default:
8583
0
      break;
8584
0
    }
8585
0
  }
8586
0
  if (dependent() || SemaRef.CurContext->isDependentContext())
8587
0
    return false;
8588
0
  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8589
0
      << S->getSourceRange() << LCDecl;
8590
0
  return true;
8591
0
}
8592
8593
static ExprResult
8594
tryBuildCapture(Sema &SemaRef, Expr *Capture,
8595
                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8596
0
                StringRef Name = ".capture_expr.") {
8597
0
  if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8598
0
    return Capture;
8599
0
  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8600
0
    return SemaRef.PerformImplicitConversion(
8601
0
        Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8602
0
        /*AllowExplicit=*/true);
8603
0
  auto I = Captures.find(Capture);
8604
0
  if (I != Captures.end())
8605
0
    return buildCapture(SemaRef, Capture, I->second, Name);
8606
0
  DeclRefExpr *Ref = nullptr;
8607
0
  ExprResult Res = buildCapture(SemaRef, Capture, Ref, Name);
8608
0
  Captures[Capture] = Ref;
8609
0
  return Res;
8610
0
}
8611
8612
/// Calculate number of iterations, transforming to unsigned, if number of
8613
/// iterations may be larger than the original type.
8614
static Expr *
8615
calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8616
                  Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8617
                  bool TestIsStrictOp, bool RoundToStep,
8618
0
                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8619
0
  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8620
0
  if (!NewStep.isUsable())
8621
0
    return nullptr;
8622
0
  llvm::APSInt LRes, SRes;
8623
0
  bool IsLowerConst = false, IsStepConst = false;
8624
0
  if (std::optional<llvm::APSInt> Res =
8625
0
          Lower->getIntegerConstantExpr(SemaRef.Context)) {
8626
0
    LRes = *Res;
8627
0
    IsLowerConst = true;
8628
0
  }
8629
0
  if (std::optional<llvm::APSInt> Res =
8630
0
          Step->getIntegerConstantExpr(SemaRef.Context)) {
8631
0
    SRes = *Res;
8632
0
    IsStepConst = true;
8633
0
  }
8634
0
  bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8635
0
                         ((!TestIsStrictOp && LRes.isNonNegative()) ||
8636
0
                          (TestIsStrictOp && LRes.isStrictlyPositive()));
8637
0
  bool NeedToReorganize = false;
8638
  // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8639
0
  if (!NoNeedToConvert && IsLowerConst &&
8640
0
      (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8641
0
    NoNeedToConvert = true;
8642
0
    if (RoundToStep) {
8643
0
      unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8644
0
                        ? LRes.getBitWidth()
8645
0
                        : SRes.getBitWidth();
8646
0
      LRes = LRes.extend(BW + 1);
8647
0
      LRes.setIsSigned(true);
8648
0
      SRes = SRes.extend(BW + 1);
8649
0
      SRes.setIsSigned(true);
8650
0
      LRes -= SRes;
8651
0
      NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8652
0
      LRes = LRes.trunc(BW);
8653
0
    }
8654
0
    if (TestIsStrictOp) {
8655
0
      unsigned BW = LRes.getBitWidth();
8656
0
      LRes = LRes.extend(BW + 1);
8657
0
      LRes.setIsSigned(true);
8658
0
      ++LRes;
8659
0
      NoNeedToConvert =
8660
0
          NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8661
      // truncate to the original bitwidth.
8662
0
      LRes = LRes.trunc(BW);
8663
0
    }
8664
0
    NeedToReorganize = NoNeedToConvert;
8665
0
  }
8666
0
  llvm::APSInt URes;
8667
0
  bool IsUpperConst = false;
8668
0
  if (std::optional<llvm::APSInt> Res =
8669
0
          Upper->getIntegerConstantExpr(SemaRef.Context)) {
8670
0
    URes = *Res;
8671
0
    IsUpperConst = true;
8672
0
  }
8673
0
  if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8674
0
      (!RoundToStep || IsStepConst)) {
8675
0
    unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8676
0
                                                          : URes.getBitWidth();
8677
0
    LRes = LRes.extend(BW + 1);
8678
0
    LRes.setIsSigned(true);
8679
0
    URes = URes.extend(BW + 1);
8680
0
    URes.setIsSigned(true);
8681
0
    URes -= LRes;
8682
0
    NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8683
0
    NeedToReorganize = NoNeedToConvert;
8684
0
  }
8685
  // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8686
  // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8687
  // unsigned.
8688
0
  if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8689
0
      !LCTy->isDependentType() && LCTy->isIntegerType()) {
8690
0
    QualType LowerTy = Lower->getType();
8691
0
    QualType UpperTy = Upper->getType();
8692
0
    uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8693
0
    uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8694
0
    if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8695
0
        (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8696
0
      QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8697
0
          LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8698
0
      Upper =
8699
0
          SemaRef
8700
0
              .PerformImplicitConversion(
8701
0
                  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8702
0
                  CastType, Sema::AA_Converting)
8703
0
              .get();
8704
0
      Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8705
0
      NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8706
0
    }
8707
0
  }
8708
0
  if (!Lower || !Upper || NewStep.isInvalid())
8709
0
    return nullptr;
8710
8711
0
  ExprResult Diff;
8712
  // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8713
  // 1]).
8714
0
  if (NeedToReorganize) {
8715
0
    Diff = Lower;
8716
8717
0
    if (RoundToStep) {
8718
      // Lower - Step
8719
0
      Diff =
8720
0
          SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8721
0
      if (!Diff.isUsable())
8722
0
        return nullptr;
8723
0
    }
8724
8725
    // Lower - Step [+ 1]
8726
0
    if (TestIsStrictOp)
8727
0
      Diff = SemaRef.BuildBinOp(
8728
0
          S, DefaultLoc, BO_Add, Diff.get(),
8729
0
          SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8730
0
    if (!Diff.isUsable())
8731
0
      return nullptr;
8732
8733
0
    Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8734
0
    if (!Diff.isUsable())
8735
0
      return nullptr;
8736
8737
    // Upper - (Lower - Step [+ 1]).
8738
0
    Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8739
0
    if (!Diff.isUsable())
8740
0
      return nullptr;
8741
0
  } else {
8742
0
    Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8743
8744
0
    if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8745
      // BuildBinOp already emitted error, this one is to point user to upper
8746
      // and lower bound, and to tell what is passed to 'operator-'.
8747
0
      SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8748
0
          << Upper->getSourceRange() << Lower->getSourceRange();
8749
0
      return nullptr;
8750
0
    }
8751
8752
0
    if (!Diff.isUsable())
8753
0
      return nullptr;
8754
8755
    // Upper - Lower [- 1]
8756
0
    if (TestIsStrictOp)
8757
0
      Diff = SemaRef.BuildBinOp(
8758
0
          S, DefaultLoc, BO_Sub, Diff.get(),
8759
0
          SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8760
0
    if (!Diff.isUsable())
8761
0
      return nullptr;
8762
8763
0
    if (RoundToStep) {
8764
      // Upper - Lower [- 1] + Step
8765
0
      Diff =
8766
0
          SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8767
0
      if (!Diff.isUsable())
8768
0
        return nullptr;
8769
0
    }
8770
0
  }
8771
8772
  // Parentheses (for dumping/debugging purposes only).
8773
0
  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8774
0
  if (!Diff.isUsable())
8775
0
    return nullptr;
8776
8777
  // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8778
0
  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8779
0
  if (!Diff.isUsable())
8780
0
    return nullptr;
8781
8782
0
  return Diff.get();
8783
0
}
8784
8785
/// Build the expression to calculate the number of iterations.
8786
Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8787
    Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8788
0
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8789
0
  QualType VarType = LCDecl->getType().getNonReferenceType();
8790
0
  if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8791
0
      !SemaRef.getLangOpts().CPlusPlus)
8792
0
    return nullptr;
8793
0
  Expr *LBVal = LB;
8794
0
  Expr *UBVal = UB;
8795
  // OuterVar = (LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8796
  // max(LB(MinVal), LB(MaxVal)))
8797
0
  if (InitDependOnLC) {
8798
0
    const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8799
0
    if (!IS.MinValue || !IS.MaxValue)
8800
0
      return nullptr;
8801
    // OuterVar = Min
8802
0
    ExprResult MinValue =
8803
0
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8804
0
    if (!MinValue.isUsable())
8805
0
      return nullptr;
8806
8807
0
    ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8808
0
                                             IS.CounterVar, MinValue.get());
8809
0
    if (!LBMinVal.isUsable())
8810
0
      return nullptr;
8811
    // OuterVar = Min, LBVal
8812
0
    LBMinVal =
8813
0
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8814
0
    if (!LBMinVal.isUsable())
8815
0
      return nullptr;
8816
    // (OuterVar = Min, LBVal)
8817
0
    LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8818
0
    if (!LBMinVal.isUsable())
8819
0
      return nullptr;
8820
8821
    // OuterVar = Max
8822
0
    ExprResult MaxValue =
8823
0
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8824
0
    if (!MaxValue.isUsable())
8825
0
      return nullptr;
8826
8827
0
    ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8828
0
                                             IS.CounterVar, MaxValue.get());
8829
0
    if (!LBMaxVal.isUsable())
8830
0
      return nullptr;
8831
    // OuterVar = Max, LBVal
8832
0
    LBMaxVal =
8833
0
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8834
0
    if (!LBMaxVal.isUsable())
8835
0
      return nullptr;
8836
    // (OuterVar = Max, LBVal)
8837
0
    LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8838
0
    if (!LBMaxVal.isUsable())
8839
0
      return nullptr;
8840
8841
0
    Expr *LBMin =
8842
0
        tryBuildCapture(SemaRef, LBMinVal.get(), Captures, ".lb_min").get();
8843
0
    Expr *LBMax =
8844
0
        tryBuildCapture(SemaRef, LBMaxVal.get(), Captures, ".lb_max").get();
8845
0
    if (!LBMin || !LBMax)
8846
0
      return nullptr;
8847
    // LB(MinVal) < LB(MaxVal)
8848
0
    ExprResult MinLessMaxRes =
8849
0
        SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8850
0
    if (!MinLessMaxRes.isUsable())
8851
0
      return nullptr;
8852
0
    Expr *MinLessMax =
8853
0
        tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures, ".min_less_max")
8854
0
            .get();
8855
0
    if (!MinLessMax)
8856
0
      return nullptr;
8857
0
    if (*TestIsLessOp) {
8858
      // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8859
      // LB(MaxVal))
8860
0
      ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8861
0
                                                    MinLessMax, LBMin, LBMax);
8862
0
      if (!MinLB.isUsable())
8863
0
        return nullptr;
8864
0
      LBVal = MinLB.get();
8865
0
    } else {
8866
      // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8867
      // LB(MaxVal))
8868
0
      ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8869
0
                                                    MinLessMax, LBMax, LBMin);
8870
0
      if (!MaxLB.isUsable())
8871
0
        return nullptr;
8872
0
      LBVal = MaxLB.get();
8873
0
    }
8874
    // OuterVar = LB
8875
0
    LBMinVal =
8876
0
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8877
0
    if (!LBMinVal.isUsable())
8878
0
      return nullptr;
8879
0
    LBVal = LBMinVal.get();
8880
0
  }
8881
  // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8882
  // min(UB(MinVal), UB(MaxVal))
8883
0
  if (CondDependOnLC) {
8884
0
    const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8885
0
    if (!IS.MinValue || !IS.MaxValue)
8886
0
      return nullptr;
8887
    // OuterVar = Min
8888
0
    ExprResult MinValue =
8889
0
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8890
0
    if (!MinValue.isUsable())
8891
0
      return nullptr;
8892
8893
0
    ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8894
0
                                             IS.CounterVar, MinValue.get());
8895
0
    if (!UBMinVal.isUsable())
8896
0
      return nullptr;
8897
    // OuterVar = Min, UBVal
8898
0
    UBMinVal =
8899
0
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8900
0
    if (!UBMinVal.isUsable())
8901
0
      return nullptr;
8902
    // (OuterVar = Min, UBVal)
8903
0
    UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8904
0
    if (!UBMinVal.isUsable())
8905
0
      return nullptr;
8906
8907
    // OuterVar = Max
8908
0
    ExprResult MaxValue =
8909
0
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8910
0
    if (!MaxValue.isUsable())
8911
0
      return nullptr;
8912
8913
0
    ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8914
0
                                             IS.CounterVar, MaxValue.get());
8915
0
    if (!UBMaxVal.isUsable())
8916
0
      return nullptr;
8917
    // OuterVar = Max, UBVal
8918
0
    UBMaxVal =
8919
0
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8920
0
    if (!UBMaxVal.isUsable())
8921
0
      return nullptr;
8922
    // (OuterVar = Max, UBVal)
8923
0
    UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8924
0
    if (!UBMaxVal.isUsable())
8925
0
      return nullptr;
8926
8927
0
    Expr *UBMin =
8928
0
        tryBuildCapture(SemaRef, UBMinVal.get(), Captures, ".ub_min").get();
8929
0
    Expr *UBMax =
8930
0
        tryBuildCapture(SemaRef, UBMaxVal.get(), Captures, ".ub_max").get();
8931
0
    if (!UBMin || !UBMax)
8932
0
      return nullptr;
8933
    // UB(MinVal) > UB(MaxVal)
8934
0
    ExprResult MinGreaterMaxRes =
8935
0
        SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8936
0
    if (!MinGreaterMaxRes.isUsable())
8937
0
      return nullptr;
8938
0
    Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.get(),
8939
0
                                          Captures, ".min_greater_max")
8940
0
                              .get();
8941
0
    if (!MinGreaterMax)
8942
0
      return nullptr;
8943
0
    if (*TestIsLessOp) {
8944
      // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8945
      // UB(MaxVal))
8946
0
      ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8947
0
          DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8948
0
      if (!MaxUB.isUsable())
8949
0
        return nullptr;
8950
0
      UBVal = MaxUB.get();
8951
0
    } else {
8952
      // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8953
      // UB(MaxVal))
8954
0
      ExprResult MinUB = SemaRef.ActOnConditionalOp(
8955
0
          DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8956
0
      if (!MinUB.isUsable())
8957
0
        return nullptr;
8958
0
      UBVal = MinUB.get();
8959
0
    }
8960
0
  }
8961
0
  Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
8962
0
  Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
8963
0
  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures, ".upper").get();
8964
0
  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures, ".lower").get();
8965
0
  if (!Upper || !Lower)
8966
0
    return nullptr;
8967
8968
0
  ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8969
0
                                      Step, VarType, TestIsStrictOp,
8970
0
                                      /*RoundToStep=*/true, Captures);
8971
0
  if (!Diff.isUsable())
8972
0
    return nullptr;
8973
8974
  // OpenMP runtime requires 32-bit or 64-bit loop variables.
8975
0
  QualType Type = Diff.get()->getType();
8976
0
  ASTContext &C = SemaRef.Context;
8977
0
  bool UseVarType = VarType->hasIntegerRepresentation() &&
8978
0
                    C.getTypeSize(Type) > C.getTypeSize(VarType);
8979
0
  if (!Type->isIntegerType() || UseVarType) {
8980
0
    unsigned NewSize =
8981
0
        UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8982
0
    bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8983
0
                               : Type->hasSignedIntegerRepresentation();
8984
0
    Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8985
0
    if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8986
0
      Diff = SemaRef.PerformImplicitConversion(
8987
0
          Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8988
0
      if (!Diff.isUsable())
8989
0
        return nullptr;
8990
0
    }
8991
0
  }
8992
0
  if (LimitedType) {
8993
0
    unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8994
0
    if (NewSize != C.getTypeSize(Type)) {
8995
0
      if (NewSize < C.getTypeSize(Type)) {
8996
0
        assert(NewSize == 64 && "incorrect loop var size");
8997
0
        SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8998
0
            << InitSrcRange << ConditionSrcRange;
8999
0
      }
9000
0
      QualType NewType = C.getIntTypeForBitwidth(
9001
0
          NewSize, Type->hasSignedIntegerRepresentation() ||
9002
0
                       C.getTypeSize(Type) < NewSize);
9003
0
      if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
9004
0
        Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
9005
0
                                                 Sema::AA_Converting, true);
9006
0
        if (!Diff.isUsable())
9007
0
          return nullptr;
9008
0
      }
9009
0
    }
9010
0
  }
9011
9012
0
  return Diff.get();
9013
0
}
9014
9015
std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
9016
0
    Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
9017
  // Do not build for iterators, they cannot be used in non-rectangular loop
9018
  // nests.
9019
0
  if (LCDecl->getType()->isRecordType())
9020
0
    return std::make_pair(nullptr, nullptr);
9021
  // If we subtract, the min is in the condition, otherwise the min is in the
9022
  // init value.
9023
0
  Expr *MinExpr = nullptr;
9024
0
  Expr *MaxExpr = nullptr;
9025
0
  Expr *LBExpr = *TestIsLessOp ? LB : UB;
9026
0
  Expr *UBExpr = *TestIsLessOp ? UB : LB;
9027
0
  bool LBNonRect =
9028
0
      *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
9029
0
  bool UBNonRect =
9030
0
      *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
9031
0
  Expr *Lower =
9032
0
      LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
9033
0
  Expr *Upper =
9034
0
      UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
9035
0
  if (!Upper || !Lower)
9036
0
    return std::make_pair(nullptr, nullptr);
9037
9038
0
  if (*TestIsLessOp)
9039
0
    MinExpr = Lower;
9040
0
  else
9041
0
    MaxExpr = Upper;
9042
9043
  // Build minimum/maximum value based on number of iterations.
9044
0
  QualType VarType = LCDecl->getType().getNonReferenceType();
9045
9046
0
  ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
9047
0
                                      Step, VarType, TestIsStrictOp,
9048
0
                                      /*RoundToStep=*/false, Captures);
9049
0
  if (!Diff.isUsable())
9050
0
    return std::make_pair(nullptr, nullptr);
9051
9052
  // ((Upper - Lower [- 1]) / Step) * Step
9053
  // Parentheses (for dumping/debugging purposes only).
9054
0
  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
9055
0
  if (!Diff.isUsable())
9056
0
    return std::make_pair(nullptr, nullptr);
9057
9058
0
  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
9059
0
  if (!NewStep.isUsable())
9060
0
    return std::make_pair(nullptr, nullptr);
9061
0
  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
9062
0
  if (!Diff.isUsable())
9063
0
    return std::make_pair(nullptr, nullptr);
9064
9065
  // Parentheses (for dumping/debugging purposes only).
9066
0
  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
9067
0
  if (!Diff.isUsable())
9068
0
    return std::make_pair(nullptr, nullptr);
9069
9070
  // Convert to the ptrdiff_t, if original type is pointer.
9071
0
  if (VarType->isAnyPointerType() &&
9072
0
      !SemaRef.Context.hasSameType(
9073
0
          Diff.get()->getType(),
9074
0
          SemaRef.Context.getUnsignedPointerDiffType())) {
9075
0
    Diff = SemaRef.PerformImplicitConversion(
9076
0
        Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
9077
0
        Sema::AA_Converting, /*AllowExplicit=*/true);
9078
0
  }
9079
0
  if (!Diff.isUsable())
9080
0
    return std::make_pair(nullptr, nullptr);
9081
9082
0
  if (*TestIsLessOp) {
9083
    // MinExpr = Lower;
9084
    // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
9085
0
    Diff = SemaRef.BuildBinOp(
9086
0
        S, DefaultLoc, BO_Add,
9087
0
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
9088
0
        Diff.get());
9089
0
    if (!Diff.isUsable())
9090
0
      return std::make_pair(nullptr, nullptr);
9091
0
  } else {
9092
    // MaxExpr = Upper;
9093
    // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
9094
0
    Diff = SemaRef.BuildBinOp(
9095
0
        S, DefaultLoc, BO_Sub,
9096
0
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
9097
0
        Diff.get());
9098
0
    if (!Diff.isUsable())
9099
0
      return std::make_pair(nullptr, nullptr);
9100
0
  }
9101
9102
  // Convert to the original type.
9103
0
  if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
9104
0
    Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
9105
0
                                             Sema::AA_Converting,
9106
0
                                             /*AllowExplicit=*/true);
9107
0
  if (!Diff.isUsable())
9108
0
    return std::make_pair(nullptr, nullptr);
9109
9110
0
  Sema::TentativeAnalysisScope Trap(SemaRef);
9111
0
  Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
9112
0
  if (!Diff.isUsable())
9113
0
    return std::make_pair(nullptr, nullptr);
9114
9115
0
  if (*TestIsLessOp)
9116
0
    MaxExpr = Diff.get();
9117
0
  else
9118
0
    MinExpr = Diff.get();
9119
9120
0
  return std::make_pair(MinExpr, MaxExpr);
9121
0
}
9122
9123
0
Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
9124
0
  if (InitDependOnLC || CondDependOnLC)
9125
0
    return Condition;
9126
0
  return nullptr;
9127
0
}
9128
9129
Expr *OpenMPIterationSpaceChecker::buildPreCond(
9130
    Scope *S, Expr *Cond,
9131
0
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
9132
  // Do not build a precondition when the condition/initialization is dependent
9133
  // to prevent pessimistic early loop exit.
9134
  // TODO: this can be improved by calculating min/max values but not sure that
9135
  // it will be very effective.
9136
0
  if (CondDependOnLC || InitDependOnLC)
9137
0
    return SemaRef
9138
0
        .PerformImplicitConversion(
9139
0
            SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
9140
0
            SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
9141
0
            /*AllowExplicit=*/true)
9142
0
        .get();
9143
9144
  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
9145
0
  Sema::TentativeAnalysisScope Trap(SemaRef);
9146
9147
0
  ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
9148
0
  ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
9149
0
  if (!NewLB.isUsable() || !NewUB.isUsable())
9150
0
    return nullptr;
9151
9152
0
  ExprResult CondExpr =
9153
0
      SemaRef.BuildBinOp(S, DefaultLoc,
9154
0
                         *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
9155
0
                                       : (TestIsStrictOp ? BO_GT : BO_GE),
9156
0
                         NewLB.get(), NewUB.get());
9157
0
  if (CondExpr.isUsable()) {
9158
0
    if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
9159
0
                                                SemaRef.Context.BoolTy))
9160
0
      CondExpr = SemaRef.PerformImplicitConversion(
9161
0
          CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
9162
0
          /*AllowExplicit=*/true);
9163
0
  }
9164
9165
  // Otherwise use original loop condition and evaluate it in runtime.
9166
0
  return CondExpr.isUsable() ? CondExpr.get() : Cond;
9167
0
}
9168
9169
/// Build reference expression to the counter be used for codegen.
9170
DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
9171
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9172
0
    DSAStackTy &DSA) const {
9173
0
  auto *VD = dyn_cast<VarDecl>(LCDecl);
9174
0
  if (!VD) {
9175
0
    VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
9176
0
    DeclRefExpr *Ref = buildDeclRefExpr(
9177
0
        SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
9178
0
    const DSAStackTy::DSAVarData Data =
9179
0
        DSA.getTopDSA(LCDecl, /*FromParent=*/false);
9180
    // If the loop control decl is explicitly marked as private, do not mark it
9181
    // as captured again.
9182
0
    if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
9183
0
      Captures.insert(std::make_pair(LCRef, Ref));
9184
0
    return Ref;
9185
0
  }
9186
0
  return cast<DeclRefExpr>(LCRef);
9187
0
}
9188
9189
0
Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
9190
0
  if (LCDecl && !LCDecl->isInvalidDecl()) {
9191
0
    QualType Type = LCDecl->getType().getNonReferenceType();
9192
0
    VarDecl *PrivateVar = buildVarDecl(
9193
0
        SemaRef, DefaultLoc, Type, LCDecl->getName(),
9194
0
        LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
9195
0
        isa<VarDecl>(LCDecl)
9196
0
            ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
9197
0
            : nullptr);
9198
0
    if (PrivateVar->isInvalidDecl())
9199
0
      return nullptr;
9200
0
    return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
9201
0
  }
9202
0
  return nullptr;
9203
0
}
9204
9205
/// Build initialization of the counter to be used for codegen.
9206
0
Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
9207
9208
/// Build step of the counter be used for codegen.
9209
0
Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
9210
9211
Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9212
    Scope *S, Expr *Counter,
9213
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
9214
0
    Expr *Inc, OverloadedOperatorKind OOK) {
9215
0
  Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
9216
0
  if (!Cnt)
9217
0
    return nullptr;
9218
0
  if (Inc) {
9219
0
    assert((OOK == OO_Plus || OOK == OO_Minus) &&
9220
0
           "Expected only + or - operations for depend clauses.");
9221
0
    BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
9222
0
    Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
9223
0
    if (!Cnt)
9224
0
      return nullptr;
9225
0
  }
9226
0
  QualType VarType = LCDecl->getType().getNonReferenceType();
9227
0
  if (!VarType->isIntegerType() && !VarType->isPointerType() &&
9228
0
      !SemaRef.getLangOpts().CPlusPlus)
9229
0
    return nullptr;
9230
  // Upper - Lower
9231
0
  Expr *Upper =
9232
0
      *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9233
0
  Expr *Lower =
9234
0
      *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9235
0
  if (!Upper || !Lower)
9236
0
    return nullptr;
9237
9238
0
  ExprResult Diff = calculateNumIters(
9239
0
      SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9240
0
      /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
9241
0
  if (!Diff.isUsable())
9242
0
    return nullptr;
9243
9244
0
  return Diff.get();
9245
0
}
9246
} // namespace
9247
9248
0
void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
9249
0
  assert(getLangOpts().OpenMP && "OpenMP is not active.");
9250
0
  assert(Init && "Expected loop in canonical form.");
9251
0
  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
9252
0
  if (AssociatedLoops > 0 &&
9253
0
      isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
9254
0
    DSAStack->loopStart();
9255
0
    OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
9256
0
                                    *DSAStack, ForLoc);
9257
0
    if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
9258
0
      if (ValueDecl *D = ISC.getLoopDecl()) {
9259
0
        auto *VD = dyn_cast<VarDecl>(D);
9260
0
        DeclRefExpr *PrivateRef = nullptr;
9261
0
        if (!VD) {
9262
0
          if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
9263
0
            VD = Private;
9264
0
          } else {
9265
0
            PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
9266
0
                                      /*WithInit=*/false);
9267
0
            VD = cast<VarDecl>(PrivateRef->getDecl());
9268
0
          }
9269
0
        }
9270
0
        DSAStack->addLoopControlVariable(D, VD);
9271
0
        const Decl *LD = DSAStack->getPossiblyLoopCunter();
9272
0
        if (LD != D->getCanonicalDecl()) {
9273
0
          DSAStack->resetPossibleLoopCounter();
9274
0
          if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
9275
0
            MarkDeclarationsReferencedInExpr(
9276
0
                buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
9277
0
                                 Var->getType().getNonLValueExprType(Context),
9278
0
                                 ForLoc, /*RefersToCapture=*/true));
9279
0
        }
9280
0
        OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9281
        // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9282
        // Referenced in a Construct, C/C++]. The loop iteration variable in the
9283
        // associated for-loop of a simd construct with just one associated
9284
        // for-loop may be listed in a linear clause with a constant-linear-step
9285
        // that is the increment of the associated for-loop. The loop iteration
9286
        // variable(s) in the associated for-loop(s) of a for or parallel for
9287
        // construct may be listed in a private or lastprivate clause.
9288
0
        DSAStackTy::DSAVarData DVar =
9289
0
            DSAStack->getTopDSA(D, /*FromParent=*/false);
9290
        // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9291
        // is declared in the loop and it is predetermined as a private.
9292
0
        Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9293
0
        OpenMPClauseKind PredeterminedCKind =
9294
0
            isOpenMPSimdDirective(DKind)
9295
0
                ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9296
0
                : OMPC_private;
9297
0
        if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9298
0
              DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9299
0
              (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9300
0
                                         DVar.CKind != OMPC_private))) ||
9301
0
             ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
9302
0
               DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9303
0
               DKind == OMPD_parallel_master_taskloop ||
9304
0
               DKind == OMPD_parallel_masked_taskloop ||
9305
0
               isOpenMPDistributeDirective(DKind)) &&
9306
0
              !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9307
0
              DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9308
0
            (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9309
0
          Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9310
0
              << getOpenMPClauseName(DVar.CKind)
9311
0
              << getOpenMPDirectiveName(DKind)
9312
0
              << getOpenMPClauseName(PredeterminedCKind);
9313
0
          if (DVar.RefExpr == nullptr)
9314
0
            DVar.CKind = PredeterminedCKind;
9315
0
          reportOriginalDsa(*this, DSAStack, D, DVar,
9316
0
                            /*IsLoopIterVar=*/true);
9317
0
        } else if (LoopDeclRefExpr) {
9318
          // Make the loop iteration variable private (for worksharing
9319
          // constructs), linear (for simd directives with the only one
9320
          // associated loop) or lastprivate (for simd directives with several
9321
          // collapsed or ordered loops).
9322
0
          if (DVar.CKind == OMPC_unknown)
9323
0
            DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9324
0
                             PrivateRef);
9325
0
        }
9326
0
      }
9327
0
    }
9328
0
    DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9329
0
  }
9330
0
}
9331
9332
namespace {
9333
// Utility for openmp doacross clause kind
9334
class OMPDoacrossKind {
9335
public:
9336
0
  bool isSource(const OMPDoacrossClause *C) {
9337
0
    return C->getDependenceType() == OMPC_DOACROSS_source ||
9338
0
           C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
9339
0
  }
9340
0
  bool isSink(const OMPDoacrossClause *C) {
9341
0
    return C->getDependenceType() == OMPC_DOACROSS_sink;
9342
0
  }
9343
0
  bool isSinkIter(const OMPDoacrossClause *C) {
9344
0
    return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
9345
0
  }
9346
};
9347
} // namespace
9348
/// Called on a for stmt to check and extract its iteration space
9349
/// for further processing (such as collapsing).
9350
static bool checkOpenMPIterationSpace(
9351
    OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
9352
    unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
9353
    unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
9354
    Expr *OrderedLoopCountExpr,
9355
    Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9356
    llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
9357
0
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9358
0
  bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
9359
  // OpenMP [2.9.1, Canonical Loop Form]
9360
  //   for (init-expr; test-expr; incr-expr) structured-block
9361
  //   for (range-decl: range-expr) structured-block
9362
0
  if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9363
0
    S = CanonLoop->getLoopStmt();
9364
0
  auto *For = dyn_cast_or_null<ForStmt>(S);
9365
0
  auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9366
  // Ranged for is supported only in OpenMP 5.0.
9367
0
  if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
9368
0
    OpenMPDirectiveKind DK = (SemaRef.getLangOpts().OpenMP < 50 ||
9369
0
                              DSA.getMappedDirective() == OMPD_unknown)
9370
0
                                 ? DKind
9371
0
                                 : DSA.getMappedDirective();
9372
0
    SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
9373
0
        << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
9374
0
        << getOpenMPDirectiveName(DK) << TotalNestedLoopCount
9375
0
        << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9376
0
    if (TotalNestedLoopCount > 1) {
9377
0
      if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9378
0
        SemaRef.Diag(DSA.getConstructLoc(),
9379
0
                     diag::note_omp_collapse_ordered_expr)
9380
0
            << 2 << CollapseLoopCountExpr->getSourceRange()
9381
0
            << OrderedLoopCountExpr->getSourceRange();
9382
0
      else if (CollapseLoopCountExpr)
9383
0
        SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9384
0
                     diag::note_omp_collapse_ordered_expr)
9385
0
            << 0 << CollapseLoopCountExpr->getSourceRange();
9386
0
      else
9387
0
        SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9388
0
                     diag::note_omp_collapse_ordered_expr)
9389
0
            << 1 << OrderedLoopCountExpr->getSourceRange();
9390
0
    }
9391
0
    return true;
9392
0
  }
9393
0
  assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9394
0
         "No loop body.");
9395
  // Postpone analysis in dependent contexts for ranged for loops.
9396
0
  if (CXXFor && SemaRef.CurContext->isDependentContext())
9397
0
    return false;
9398
9399
0
  OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9400
0
                                  For ? For->getForLoc() : CXXFor->getForLoc());
9401
9402
  // Check init.
9403
0
  Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
9404
0
  if (ISC.checkAndSetInit(Init))
9405
0
    return true;
9406
9407
0
  bool HasErrors = false;
9408
9409
  // Check loop variable's type.
9410
0
  if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
9411
    // OpenMP [2.6, Canonical Loop Form]
9412
    // Var is one of the following:
9413
    //   A variable of signed or unsigned integer type.
9414
    //   For C++, a variable of a random access iterator type.
9415
    //   For C, a variable of a pointer type.
9416
0
    QualType VarType = LCDecl->getType().getNonReferenceType();
9417
0
    if (!VarType->isDependentType() && !VarType->isIntegerType() &&
9418
0
        !VarType->isPointerType() &&
9419
0
        !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
9420
0
      SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9421
0
          << SemaRef.getLangOpts().CPlusPlus;
9422
0
      HasErrors = true;
9423
0
    }
9424
9425
    // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9426
    // a Construct
9427
    // The loop iteration variable(s) in the associated for-loop(s) of a for or
9428
    // parallel for construct is (are) private.
9429
    // The loop iteration variable in the associated for-loop of a simd
9430
    // construct with just one associated for-loop is linear with a
9431
    // constant-linear-step that is the increment of the associated for-loop.
9432
    // Exclude loop var from the list of variables with implicitly defined data
9433
    // sharing attributes.
9434
0
    VarsWithImplicitDSA.erase(LCDecl);
9435
9436
0
    assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
9437
9438
    // Check test-expr.
9439
0
    HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9440
9441
    // Check incr-expr.
9442
0
    HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9443
0
  }
9444
9445
0
  if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
9446
0
    return HasErrors;
9447
9448
  // Build the loop's iteration space representation.
9449
0
  ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9450
0
      DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9451
0
  ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9452
0
      ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9453
0
                             (isOpenMPWorksharingDirective(DKind) ||
9454
0
                              isOpenMPGenericLoopDirective(DKind) ||
9455
0
                              isOpenMPTaskLoopDirective(DKind) ||
9456
0
                              isOpenMPDistributeDirective(DKind) ||
9457
0
                              isOpenMPLoopTransformationDirective(DKind)),
9458
0
                             Captures);
9459
0
  ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9460
0
      ISC.buildCounterVar(Captures, DSA);
9461
0
  ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9462
0
      ISC.buildPrivateCounterVar();
9463
0
  ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9464
0
  ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9465
0
  ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9466
0
  ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9467
0
      ISC.getConditionSrcRange();
9468
0
  ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9469
0
      ISC.getIncrementSrcRange();
9470
0
  ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9471
0
  ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9472
0
      ISC.isStrictTestOp();
9473
0
  std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9474
0
           ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9475
0
      ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9476
0
  ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9477
0
      ISC.buildFinalCondition(DSA.getCurScope());
9478
0
  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9479
0
      ISC.doesInitDependOnLC();
9480
0
  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9481
0
      ISC.doesCondDependOnLC();
9482
0
  ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9483
0
      ISC.getLoopDependentIdx();
9484
9485
0
  HasErrors |=
9486
0
      (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
9487
0
       ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
9488
0
       ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
9489
0
       ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
9490
0
       ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
9491
0
       ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
9492
0
  if (!HasErrors && DSA.isOrderedRegion()) {
9493
0
    if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9494
0
      if (CurrentNestedLoopCount <
9495
0
          DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9496
0
        DSA.getOrderedRegionParam().second->setLoopNumIterations(
9497
0
            CurrentNestedLoopCount,
9498
0
            ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9499
0
        DSA.getOrderedRegionParam().second->setLoopCounter(
9500
0
            CurrentNestedLoopCount,
9501
0
            ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9502
0
      }
9503
0
    }
9504
0
    for (auto &Pair : DSA.getDoacrossDependClauses()) {
9505
0
      auto *DependC = dyn_cast<OMPDependClause>(Pair.first);
9506
0
      auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first);
9507
0
      unsigned NumLoops =
9508
0
          DependC ? DependC->getNumLoops() : DoacrossC->getNumLoops();
9509
0
      if (CurrentNestedLoopCount >= NumLoops) {
9510
        // Erroneous case - clause has some problems.
9511
0
        continue;
9512
0
      }
9513
0
      if (DependC && DependC->getDependencyKind() == OMPC_DEPEND_sink &&
9514
0
          Pair.second.size() <= CurrentNestedLoopCount) {
9515
        // Erroneous case - clause has some problems.
9516
0
        DependC->setLoopData(CurrentNestedLoopCount, nullptr);
9517
0
        continue;
9518
0
      }
9519
0
      OMPDoacrossKind ODK;
9520
0
      if (DoacrossC && ODK.isSink(DoacrossC) &&
9521
0
          Pair.second.size() <= CurrentNestedLoopCount) {
9522
        // Erroneous case - clause has some problems.
9523
0
        DoacrossC->setLoopData(CurrentNestedLoopCount, nullptr);
9524
0
        continue;
9525
0
      }
9526
0
      Expr *CntValue;
9527
0
      SourceLocation DepLoc =
9528
0
          DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc();
9529
0
      if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) ||
9530
0
          (DoacrossC && ODK.isSource(DoacrossC)))
9531
0
        CntValue = ISC.buildOrderedLoopData(
9532
0
            DSA.getCurScope(),
9533
0
            ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9534
0
            DepLoc);
9535
0
      else if (DoacrossC && ODK.isSinkIter(DoacrossC)) {
9536
0
        Expr *Cnt = SemaRef
9537
0
                        .DefaultLvalueConversion(
9538
0
                            ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
9539
0
                        .get();
9540
0
        if (!Cnt)
9541
0
          continue;
9542
        // build CounterVar - 1
9543
0
        Expr *Inc =
9544
0
            SemaRef.ActOnIntegerConstant(DoacrossC->getColonLoc(), /*Val=*/1)
9545
0
                .get();
9546
0
        CntValue = ISC.buildOrderedLoopData(
9547
0
            DSA.getCurScope(),
9548
0
            ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9549
0
            DepLoc, Inc, clang::OO_Minus);
9550
0
      } else
9551
0
        CntValue = ISC.buildOrderedLoopData(
9552
0
            DSA.getCurScope(),
9553
0
            ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9554
0
            DepLoc, Pair.second[CurrentNestedLoopCount].first,
9555
0
            Pair.second[CurrentNestedLoopCount].second);
9556
0
      if (DependC)
9557
0
        DependC->setLoopData(CurrentNestedLoopCount, CntValue);
9558
0
      else
9559
0
        DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue);
9560
0
    }
9561
0
  }
9562
9563
0
  return HasErrors;
9564
0
}
9565
9566
/// Build 'VarRef = Start.
9567
static ExprResult
9568
buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9569
                 ExprResult Start, bool IsNonRectangularLB,
9570
0
                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9571
  // Build 'VarRef = Start.
9572
0
  ExprResult NewStart = IsNonRectangularLB
9573
0
                            ? Start.get()
9574
0
                            : tryBuildCapture(SemaRef, Start.get(), Captures);
9575
0
  if (!NewStart.isUsable())
9576
0
    return ExprError();
9577
0
  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9578
0
                                   VarRef.get()->getType())) {
9579
0
    NewStart = SemaRef.PerformImplicitConversion(
9580
0
        NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9581
0
        /*AllowExplicit=*/true);
9582
0
    if (!NewStart.isUsable())
9583
0
      return ExprError();
9584
0
  }
9585
9586
0
  ExprResult Init =
9587
0
      SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9588
0
  return Init;
9589
0
}
9590
9591
/// Build 'VarRef = Start + Iter * Step'.
9592
static ExprResult buildCounterUpdate(
9593
    Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9594
    ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9595
    bool IsNonRectangularLB,
9596
0
    llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9597
  // Add parentheses (for debugging purposes only).
9598
0
  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9599
0
  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9600
0
      !Step.isUsable())
9601
0
    return ExprError();
9602
9603
0
  ExprResult NewStep = Step;
9604
0
  if (Captures)
9605
0
    NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9606
0
  if (NewStep.isInvalid())
9607
0
    return ExprError();
9608
0
  ExprResult Update =
9609
0
      SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9610
0
  if (!Update.isUsable())
9611
0
    return ExprError();
9612
9613
  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9614
  // 'VarRef = Start (+|-) Iter * Step'.
9615
0
  if (!Start.isUsable())
9616
0
    return ExprError();
9617
0
  ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9618
0
  if (!NewStart.isUsable())
9619
0
    return ExprError();
9620
0
  if (Captures && !IsNonRectangularLB)
9621
0
    NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9622
0
  if (NewStart.isInvalid())
9623
0
    return ExprError();
9624
9625
  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9626
0
  ExprResult SavedUpdate = Update;
9627
0
  ExprResult UpdateVal;
9628
0
  if (VarRef.get()->getType()->isOverloadableType() ||
9629
0
      NewStart.get()->getType()->isOverloadableType() ||
9630
0
      Update.get()->getType()->isOverloadableType()) {
9631
0
    Sema::TentativeAnalysisScope Trap(SemaRef);
9632
9633
0
    Update =
9634
0
        SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9635
0
    if (Update.isUsable()) {
9636
0
      UpdateVal =
9637
0
          SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9638
0
                             VarRef.get(), SavedUpdate.get());
9639
0
      if (UpdateVal.isUsable()) {
9640
0
        Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9641
0
                                            UpdateVal.get());
9642
0
      }
9643
0
    }
9644
0
  }
9645
9646
  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9647
0
  if (!Update.isUsable() || !UpdateVal.isUsable()) {
9648
0
    Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9649
0
                                NewStart.get(), SavedUpdate.get());
9650
0
    if (!Update.isUsable())
9651
0
      return ExprError();
9652
9653
0
    if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9654
0
                                     VarRef.get()->getType())) {
9655
0
      Update = SemaRef.PerformImplicitConversion(
9656
0
          Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9657
0
      if (!Update.isUsable())
9658
0
        return ExprError();
9659
0
    }
9660
9661
0
    Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9662
0
  }
9663
0
  return Update;
9664
0
}
9665
9666
/// Convert integer expression \a E to make it have at least \a Bits
9667
/// bits.
9668
0
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9669
0
  if (E == nullptr)
9670
0
    return ExprError();
9671
0
  ASTContext &C = SemaRef.Context;
9672
0
  QualType OldType = E->getType();
9673
0
  unsigned HasBits = C.getTypeSize(OldType);
9674
0
  if (HasBits >= Bits)
9675
0
    return ExprResult(E);
9676
  // OK to convert to signed, because new type has more bits than old.
9677
0
  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9678
0
  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9679
0
                                           true);
9680
0
}
9681
9682
/// Check if the given expression \a E is a constant integer that fits
9683
/// into \a Bits bits.
9684
0
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9685
0
  if (E == nullptr)
9686
0
    return false;
9687
0
  if (std::optional<llvm::APSInt> Result =
9688
0
          E->getIntegerConstantExpr(SemaRef.Context))
9689
0
    return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9690
0
  return false;
9691
0
}
9692
9693
/// Build preinits statement for the given declarations.
9694
static Stmt *buildPreInits(ASTContext &Context,
9695
0
                           MutableArrayRef<Decl *> PreInits) {
9696
0
  if (!PreInits.empty()) {
9697
0
    return new (Context) DeclStmt(
9698
0
        DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9699
0
        SourceLocation(), SourceLocation());
9700
0
  }
9701
0
  return nullptr;
9702
0
}
9703
9704
/// Build preinits statement for the given declarations.
9705
static Stmt *
9706
buildPreInits(ASTContext &Context,
9707
0
              const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9708
0
  if (!Captures.empty()) {
9709
0
    SmallVector<Decl *, 16> PreInits;
9710
0
    for (const auto &Pair : Captures)
9711
0
      PreInits.push_back(Pair.second->getDecl());
9712
0
    return buildPreInits(Context, PreInits);
9713
0
  }
9714
0
  return nullptr;
9715
0
}
9716
9717
/// Build postupdate expression for the given list of postupdates expressions.
9718
0
static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9719
0
  Expr *PostUpdate = nullptr;
9720
0
  if (!PostUpdates.empty()) {
9721
0
    for (Expr *E : PostUpdates) {
9722
0
      Expr *ConvE = S.BuildCStyleCastExpr(
9723
0
                         E->getExprLoc(),
9724
0
                         S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9725
0
                         E->getExprLoc(), E)
9726
0
                        .get();
9727
0
      PostUpdate = PostUpdate
9728
0
                       ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9729
0
                                              PostUpdate, ConvE)
9730
0
                             .get()
9731
0
                       : ConvE;
9732
0
    }
9733
0
  }
9734
0
  return PostUpdate;
9735
0
}
9736
9737
/// Called on a for stmt to check itself and nested loops (if any).
9738
/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9739
/// number of collapsed loops otherwise.
9740
static unsigned
9741
checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9742
                Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9743
                DSAStackTy &DSA,
9744
                Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9745
0
                OMPLoopBasedDirective::HelperExprs &Built) {
9746
0
  unsigned NestedLoopCount = 1;
9747
0
  bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9748
0
                                    !isOpenMPLoopTransformationDirective(DKind);
9749
9750
0
  if (CollapseLoopCountExpr) {
9751
    // Found 'collapse' clause - calculate collapse number.
9752
0
    Expr::EvalResult Result;
9753
0
    if (!CollapseLoopCountExpr->isValueDependent() &&
9754
0
        CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9755
0
      NestedLoopCount = Result.Val.getInt().getLimitedValue();
9756
0
    } else {
9757
0
      Built.clear(/*Size=*/1);
9758
0
      return 1;
9759
0
    }
9760
0
  }
9761
0
  unsigned OrderedLoopCount = 1;
9762
0
  if (OrderedLoopCountExpr) {
9763
    // Found 'ordered' clause - calculate collapse number.
9764
0
    Expr::EvalResult EVResult;
9765
0
    if (!OrderedLoopCountExpr->isValueDependent() &&
9766
0
        OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9767
0
                                            SemaRef.getASTContext())) {
9768
0
      llvm::APSInt Result = EVResult.Val.getInt();
9769
0
      if (Result.getLimitedValue() < NestedLoopCount) {
9770
0
        SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9771
0
                     diag::err_omp_wrong_ordered_loop_count)
9772
0
            << OrderedLoopCountExpr->getSourceRange();
9773
0
        SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9774
0
                     diag::note_collapse_loop_count)
9775
0
            << CollapseLoopCountExpr->getSourceRange();
9776
0
      }
9777
0
      OrderedLoopCount = Result.getLimitedValue();
9778
0
    } else {
9779
0
      Built.clear(/*Size=*/1);
9780
0
      return 1;
9781
0
    }
9782
0
  }
9783
  // This is helper routine for loop directives (e.g., 'for', 'simd',
9784
  // 'for simd', etc.).
9785
0
  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9786
0
  unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9787
0
  SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9788
0
  if (!OMPLoopBasedDirective::doForAllLoops(
9789
0
          AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9790
0
          SupportsNonPerfectlyNested, NumLoops,
9791
0
          [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9792
0
           CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9793
0
           &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9794
0
            if (checkOpenMPIterationSpace(
9795
0
                    DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9796
0
                    NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9797
0
                    VarsWithImplicitDSA, IterSpaces, Captures))
9798
0
              return true;
9799
0
            if (Cnt > 0 && Cnt >= NestedLoopCount &&
9800
0
                IterSpaces[Cnt].CounterVar) {
9801
              // Handle initialization of captured loop iterator variables.
9802
0
              auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9803
0
              if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9804
0
                Captures[DRE] = DRE;
9805
0
              }
9806
0
            }
9807
0
            return false;
9808
0
          },
9809
0
          [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9810
0
            Stmt *DependentPreInits = Transform->getPreInits();
9811
0
            if (!DependentPreInits)
9812
0
              return;
9813
0
            for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9814
0
              auto *D = cast<VarDecl>(C);
9815
0
              DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9816
0
                                                  Transform->getBeginLoc());
9817
0
              Captures[Ref] = Ref;
9818
0
            }
9819
0
          }))
9820
0
    return 0;
9821
9822
0
  Built.clear(/* size */ NestedLoopCount);
9823
9824
0
  if (SemaRef.CurContext->isDependentContext())
9825
0
    return NestedLoopCount;
9826
9827
  // An example of what is generated for the following code:
9828
  //
9829
  //   #pragma omp simd collapse(2) ordered(2)
9830
  //   for (i = 0; i < NI; ++i)
9831
  //     for (k = 0; k < NK; ++k)
9832
  //       for (j = J0; j < NJ; j+=2) {
9833
  //         <loop body>
9834
  //       }
9835
  //
9836
  // We generate the code below.
9837
  // Note: the loop body may be outlined in CodeGen.
9838
  // Note: some counters may be C++ classes, operator- is used to find number of
9839
  // iterations and operator+= to calculate counter value.
9840
  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9841
  // or i64 is currently supported).
9842
  //
9843
  //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9844
  //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9845
  //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9846
  //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9847
  //     // similar updates for vars in clauses (e.g. 'linear')
9848
  //     <loop body (using local i and j)>
9849
  //   }
9850
  //   i = NI; // assign final values of counters
9851
  //   j = NJ;
9852
  //
9853
9854
  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9855
  // the iteration counts of the collapsed for loops.
9856
  // Precondition tests if there is at least one iteration (all conditions are
9857
  // true).
9858
0
  auto PreCond = ExprResult(IterSpaces[0].PreCond);
9859
0
  Expr *N0 = IterSpaces[0].NumIterations;
9860
0
  ExprResult LastIteration32 =
9861
0
      widenIterationCount(/*Bits=*/32,
9862
0
                          SemaRef
9863
0
                              .PerformImplicitConversion(
9864
0
                                  N0->IgnoreImpCasts(), N0->getType(),
9865
0
                                  Sema::AA_Converting, /*AllowExplicit=*/true)
9866
0
                              .get(),
9867
0
                          SemaRef);
9868
0
  ExprResult LastIteration64 = widenIterationCount(
9869
0
      /*Bits=*/64,
9870
0
      SemaRef
9871
0
          .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9872
0
                                     Sema::AA_Converting,
9873
0
                                     /*AllowExplicit=*/true)
9874
0
          .get(),
9875
0
      SemaRef);
9876
9877
0
  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9878
0
    return NestedLoopCount;
9879
9880
0
  ASTContext &C = SemaRef.Context;
9881
0
  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9882
9883
0
  Scope *CurScope = DSA.getCurScope();
9884
0
  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9885
0
    if (PreCond.isUsable()) {
9886
0
      PreCond =
9887
0
          SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9888
0
                             PreCond.get(), IterSpaces[Cnt].PreCond);
9889
0
    }
9890
0
    Expr *N = IterSpaces[Cnt].NumIterations;
9891
0
    SourceLocation Loc = N->getExprLoc();
9892
0
    AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9893
0
    if (LastIteration32.isUsable())
9894
0
      LastIteration32 = SemaRef.BuildBinOp(
9895
0
          CurScope, Loc, BO_Mul, LastIteration32.get(),
9896
0
          SemaRef
9897
0
              .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9898
0
                                         Sema::AA_Converting,
9899
0
                                         /*AllowExplicit=*/true)
9900
0
              .get());
9901
0
    if (LastIteration64.isUsable())
9902
0
      LastIteration64 = SemaRef.BuildBinOp(
9903
0
          CurScope, Loc, BO_Mul, LastIteration64.get(),
9904
0
          SemaRef
9905
0
              .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9906
0
                                         Sema::AA_Converting,
9907
0
                                         /*AllowExplicit=*/true)
9908
0
              .get());
9909
0
  }
9910
9911
  // Choose either the 32-bit or 64-bit version.
9912
0
  ExprResult LastIteration = LastIteration64;
9913
0
  if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9914
0
      (LastIteration32.isUsable() &&
9915
0
       C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9916
0
       (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9917
0
        fitsInto(
9918
0
            /*Bits=*/32,
9919
0
            LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9920
0
            LastIteration64.get(), SemaRef))))
9921
0
    LastIteration = LastIteration32;
9922
0
  QualType VType = LastIteration.get()->getType();
9923
0
  QualType RealVType = VType;
9924
0
  QualType StrideVType = VType;
9925
0
  if (isOpenMPTaskLoopDirective(DKind)) {
9926
0
    VType =
9927
0
        SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9928
0
    StrideVType =
9929
0
        SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9930
0
  }
9931
9932
0
  if (!LastIteration.isUsable())
9933
0
    return 0;
9934
9935
  // Save the number of iterations.
9936
0
  ExprResult NumIterations = LastIteration;
9937
0
  {
9938
0
    LastIteration = SemaRef.BuildBinOp(
9939
0
        CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9940
0
        LastIteration.get(),
9941
0
        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9942
0
    if (!LastIteration.isUsable())
9943
0
      return 0;
9944
0
  }
9945
9946
  // Calculate the last iteration number beforehand instead of doing this on
9947
  // each iteration. Do not do this if the number of iterations may be kfold-ed.
9948
0
  bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9949
0
  ExprResult CalcLastIteration;
9950
0
  if (!IsConstant) {
9951
0
    ExprResult SaveRef =
9952
0
        tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9953
0
    LastIteration = SaveRef;
9954
9955
    // Prepare SaveRef + 1.
9956
0
    NumIterations = SemaRef.BuildBinOp(
9957
0
        CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9958
0
        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9959
0
    if (!NumIterations.isUsable())
9960
0
      return 0;
9961
0
  }
9962
9963
0
  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9964
9965
  // Build variables passed into runtime, necessary for worksharing directives.
9966
0
  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9967
0
  if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9968
0
      isOpenMPDistributeDirective(DKind) ||
9969
0
      isOpenMPGenericLoopDirective(DKind) ||
9970
0
      isOpenMPLoopTransformationDirective(DKind)) {
9971
    // Lower bound variable, initialized with zero.
9972
0
    VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9973
0
    LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9974
0
    SemaRef.AddInitializerToDecl(LBDecl,
9975
0
                                 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9976
0
                                 /*DirectInit*/ false);
9977
9978
    // Upper bound variable, initialized with last iteration number.
9979
0
    VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9980
0
    UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9981
0
    SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9982
0
                                 /*DirectInit*/ false);
9983
9984
    // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9985
    // This will be used to implement clause 'lastprivate'.
9986
0
    QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9987
0
    VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9988
0
    IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9989
0
    SemaRef.AddInitializerToDecl(ILDecl,
9990
0
                                 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9991
0
                                 /*DirectInit*/ false);
9992
9993
    // Stride variable returned by runtime (we initialize it to 1 by default).
9994
0
    VarDecl *STDecl =
9995
0
        buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9996
0
    ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9997
0
    SemaRef.AddInitializerToDecl(STDecl,
9998
0
                                 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9999
0
                                 /*DirectInit*/ false);
10000
10001
    // Build expression: UB = min(UB, LastIteration)
10002
    // It is necessary for CodeGen of directives with static scheduling.
10003
0
    ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
10004
0
                                                UB.get(), LastIteration.get());
10005
0
    ExprResult CondOp = SemaRef.ActOnConditionalOp(
10006
0
        LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
10007
0
        LastIteration.get(), UB.get());
10008
0
    EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
10009
0
                             CondOp.get());
10010
0
    EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
10011
10012
    // If we have a combined directive that combines 'distribute', 'for' or
10013
    // 'simd' we need to be able to access the bounds of the schedule of the
10014
    // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
10015
    // by scheduling 'distribute' have to be passed to the schedule of 'for'.
10016
0
    if (isOpenMPLoopBoundSharingDirective(DKind)) {
10017
      // Lower bound variable, initialized with zero.
10018
0
      VarDecl *CombLBDecl =
10019
0
          buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
10020
0
      CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
10021
0
      SemaRef.AddInitializerToDecl(
10022
0
          CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
10023
0
          /*DirectInit*/ false);
10024
10025
      // Upper bound variable, initialized with last iteration number.
10026
0
      VarDecl *CombUBDecl =
10027
0
          buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
10028
0
      CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
10029
0
      SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
10030
0
                                   /*DirectInit*/ false);
10031
10032
0
      ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
10033
0
          CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
10034
0
      ExprResult CombCondOp =
10035
0
          SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
10036
0
                                     LastIteration.get(), CombUB.get());
10037
0
      CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
10038
0
                                   CombCondOp.get());
10039
0
      CombEUB =
10040
0
          SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
10041
10042
0
      const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
10043
      // We expect to have at least 2 more parameters than the 'parallel'
10044
      // directive does - the lower and upper bounds of the previous schedule.
10045
0
      assert(CD->getNumParams() >= 4 &&
10046
0
             "Unexpected number of parameters in loop combined directive");
10047
10048
      // Set the proper type for the bounds given what we learned from the
10049
      // enclosed loops.
10050
0
      ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
10051
0
      ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
10052
10053
      // Previous lower and upper bounds are obtained from the region
10054
      // parameters.
10055
0
      PrevLB =
10056
0
          buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
10057
0
      PrevUB =
10058
0
          buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
10059
0
    }
10060
0
  }
10061
10062
  // Build the iteration variable and its initialization before loop.
10063
0
  ExprResult IV;
10064
0
  ExprResult Init, CombInit;
10065
0
  {
10066
0
    VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
10067
0
    IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
10068
0
    Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
10069
0
                 isOpenMPGenericLoopDirective(DKind) ||
10070
0
                 isOpenMPTaskLoopDirective(DKind) ||
10071
0
                 isOpenMPDistributeDirective(DKind) ||
10072
0
                 isOpenMPLoopTransformationDirective(DKind))
10073
0
                    ? LB.get()
10074
0
                    : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
10075
0
    Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
10076
0
    Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
10077
10078
0
    if (isOpenMPLoopBoundSharingDirective(DKind)) {
10079
0
      Expr *CombRHS =
10080
0
          (isOpenMPWorksharingDirective(DKind) ||
10081
0
           isOpenMPGenericLoopDirective(DKind) ||
10082
0
           isOpenMPTaskLoopDirective(DKind) ||
10083
0
           isOpenMPDistributeDirective(DKind))
10084
0
              ? CombLB.get()
10085
0
              : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
10086
0
      CombInit =
10087
0
          SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
10088
0
      CombInit =
10089
0
          SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
10090
0
    }
10091
0
  }
10092
10093
0
  bool UseStrictCompare =
10094
0
      RealVType->hasUnsignedIntegerRepresentation() &&
10095
0
      llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
10096
0
        return LIS.IsStrictCompare;
10097
0
      });
10098
  // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
10099
  // unsigned IV)) for worksharing loops.
10100
0
  SourceLocation CondLoc = AStmt->getBeginLoc();
10101
0
  Expr *BoundUB = UB.get();
10102
0
  if (UseStrictCompare) {
10103
0
    BoundUB =
10104
0
        SemaRef
10105
0
            .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
10106
0
                        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10107
0
            .get();
10108
0
    BoundUB =
10109
0
        SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
10110
0
  }
10111
0
  ExprResult Cond =
10112
0
      (isOpenMPWorksharingDirective(DKind) ||
10113
0
       isOpenMPGenericLoopDirective(DKind) ||
10114
0
       isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
10115
0
       isOpenMPLoopTransformationDirective(DKind))
10116
0
          ? SemaRef.BuildBinOp(CurScope, CondLoc,
10117
0
                               UseStrictCompare ? BO_LT : BO_LE, IV.get(),
10118
0
                               BoundUB)
10119
0
          : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10120
0
                               NumIterations.get());
10121
0
  ExprResult CombDistCond;
10122
0
  if (isOpenMPLoopBoundSharingDirective(DKind)) {
10123
0
    CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10124
0
                                      NumIterations.get());
10125
0
  }
10126
10127
0
  ExprResult CombCond;
10128
0
  if (isOpenMPLoopBoundSharingDirective(DKind)) {
10129
0
    Expr *BoundCombUB = CombUB.get();
10130
0
    if (UseStrictCompare) {
10131
0
      BoundCombUB =
10132
0
          SemaRef
10133
0
              .BuildBinOp(
10134
0
                  CurScope, CondLoc, BO_Add, BoundCombUB,
10135
0
                  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10136
0
              .get();
10137
0
      BoundCombUB =
10138
0
          SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
10139
0
              .get();
10140
0
    }
10141
0
    CombCond =
10142
0
        SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10143
0
                           IV.get(), BoundCombUB);
10144
0
  }
10145
  // Loop increment (IV = IV + 1)
10146
0
  SourceLocation IncLoc = AStmt->getBeginLoc();
10147
0
  ExprResult Inc =
10148
0
      SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
10149
0
                         SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
10150
0
  if (!Inc.isUsable())
10151
0
    return 0;
10152
0
  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
10153
0
  Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
10154
0
  if (!Inc.isUsable())
10155
0
    return 0;
10156
10157
  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
10158
  // Used for directives with static scheduling.
10159
  // In combined construct, add combined version that use CombLB and CombUB
10160
  // base variables for the update
10161
0
  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
10162
0
  if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
10163
0
      isOpenMPGenericLoopDirective(DKind) ||
10164
0
      isOpenMPDistributeDirective(DKind) ||
10165
0
      isOpenMPLoopTransformationDirective(DKind)) {
10166
    // LB + ST
10167
0
    NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
10168
0
    if (!NextLB.isUsable())
10169
0
      return 0;
10170
    // LB = LB + ST
10171
0
    NextLB =
10172
0
        SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
10173
0
    NextLB =
10174
0
        SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
10175
0
    if (!NextLB.isUsable())
10176
0
      return 0;
10177
    // UB + ST
10178
0
    NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
10179
0
    if (!NextUB.isUsable())
10180
0
      return 0;
10181
    // UB = UB + ST
10182
0
    NextUB =
10183
0
        SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
10184
0
    NextUB =
10185
0
        SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
10186
0
    if (!NextUB.isUsable())
10187
0
      return 0;
10188
0
    if (isOpenMPLoopBoundSharingDirective(DKind)) {
10189
0
      CombNextLB =
10190
0
          SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
10191
0
      if (!NextLB.isUsable())
10192
0
        return 0;
10193
      // LB = LB + ST
10194
0
      CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
10195
0
                                      CombNextLB.get());
10196
0
      CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
10197
0
                                               /*DiscardedValue*/ false);
10198
0
      if (!CombNextLB.isUsable())
10199
0
        return 0;
10200
      // UB + ST
10201
0
      CombNextUB =
10202
0
          SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
10203
0
      if (!CombNextUB.isUsable())
10204
0
        return 0;
10205
      // UB = UB + ST
10206
0
      CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
10207
0
                                      CombNextUB.get());
10208
0
      CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
10209
0
                                               /*DiscardedValue*/ false);
10210
0
      if (!CombNextUB.isUsable())
10211
0
        return 0;
10212
0
    }
10213
0
  }
10214
10215
  // Create increment expression for distribute loop when combined in a same
10216
  // directive with for as IV = IV + ST; ensure upper bound expression based
10217
  // on PrevUB instead of NumIterations - used to implement 'for' when found
10218
  // in combination with 'distribute', like in 'distribute parallel for'
10219
0
  SourceLocation DistIncLoc = AStmt->getBeginLoc();
10220
0
  ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10221
0
  if (isOpenMPLoopBoundSharingDirective(DKind)) {
10222
0
    DistCond = SemaRef.BuildBinOp(
10223
0
        CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
10224
0
    assert(DistCond.isUsable() && "distribute cond expr was not built");
10225
10226
0
    DistInc =
10227
0
        SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
10228
0
    assert(DistInc.isUsable() && "distribute inc expr was not built");
10229
0
    DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
10230
0
                                 DistInc.get());
10231
0
    DistInc =
10232
0
        SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
10233
0
    assert(DistInc.isUsable() && "distribute inc expr was not built");
10234
10235
    // Build expression: UB = min(UB, prevUB) for #for in composite or combined
10236
    // construct
10237
0
    ExprResult NewPrevUB = PrevUB;
10238
0
    SourceLocation DistEUBLoc = AStmt->getBeginLoc();
10239
0
    if (!SemaRef.Context.hasSameType(UB.get()->getType(),
10240
0
                                     PrevUB.get()->getType())) {
10241
0
      NewPrevUB = SemaRef.BuildCStyleCastExpr(
10242
0
          DistEUBLoc,
10243
0
          SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
10244
0
          DistEUBLoc, NewPrevUB.get());
10245
0
      if (!NewPrevUB.isUsable())
10246
0
        return 0;
10247
0
    }
10248
0
    ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
10249
0
                                                UB.get(), NewPrevUB.get());
10250
0
    ExprResult CondOp = SemaRef.ActOnConditionalOp(
10251
0
        DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
10252
0
    PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
10253
0
                                 CondOp.get());
10254
0
    PrevEUB =
10255
0
        SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
10256
10257
    // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
10258
    // parallel for is in combination with a distribute directive with
10259
    // schedule(static, 1)
10260
0
    Expr *BoundPrevUB = PrevUB.get();
10261
0
    if (UseStrictCompare) {
10262
0
      BoundPrevUB =
10263
0
          SemaRef
10264
0
              .BuildBinOp(
10265
0
                  CurScope, CondLoc, BO_Add, BoundPrevUB,
10266
0
                  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10267
0
              .get();
10268
0
      BoundPrevUB =
10269
0
          SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
10270
0
              .get();
10271
0
    }
10272
0
    ParForInDistCond =
10273
0
        SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10274
0
                           IV.get(), BoundPrevUB);
10275
0
  }
10276
10277
  // Build updates and final values of the loop counters.
10278
0
  bool HasErrors = false;
10279
0
  Built.Counters.resize(NestedLoopCount);
10280
0
  Built.Inits.resize(NestedLoopCount);
10281
0
  Built.Updates.resize(NestedLoopCount);
10282
0
  Built.Finals.resize(NestedLoopCount);
10283
0
  Built.DependentCounters.resize(NestedLoopCount);
10284
0
  Built.DependentInits.resize(NestedLoopCount);
10285
0
  Built.FinalsConditions.resize(NestedLoopCount);
10286
0
  {
10287
    // We implement the following algorithm for obtaining the
10288
    // original loop iteration variable values based on the
10289
    // value of the collapsed loop iteration variable IV.
10290
    //
10291
    // Let n+1 be the number of collapsed loops in the nest.
10292
    // Iteration variables (I0, I1, .... In)
10293
    // Iteration counts (N0, N1, ... Nn)
10294
    //
10295
    // Acc = IV;
10296
    //
10297
    // To compute Ik for loop k, 0 <= k <= n, generate:
10298
    //    Prod = N(k+1) * N(k+2) * ... * Nn;
10299
    //    Ik = Acc / Prod;
10300
    //    Acc -= Ik * Prod;
10301
    //
10302
0
    ExprResult Acc = IV;
10303
0
    for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10304
0
      LoopIterationSpace &IS = IterSpaces[Cnt];
10305
0
      SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
10306
0
      ExprResult Iter;
10307
10308
      // Compute prod
10309
0
      ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10310
0
      for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10311
0
        Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
10312
0
                                  IterSpaces[K].NumIterations);
10313
10314
      // Iter = Acc / Prod
10315
      // If there is at least one more inner loop to avoid
10316
      // multiplication by 1.
10317
0
      if (Cnt + 1 < NestedLoopCount)
10318
0
        Iter =
10319
0
            SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
10320
0
      else
10321
0
        Iter = Acc;
10322
0
      if (!Iter.isUsable()) {
10323
0
        HasErrors = true;
10324
0
        break;
10325
0
      }
10326
10327
      // Update Acc:
10328
      // Acc -= Iter * Prod
10329
      // Check if there is at least one more inner loop to avoid
10330
      // multiplication by 1.
10331
0
      if (Cnt + 1 < NestedLoopCount)
10332
0
        Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
10333
0
                                  Prod.get());
10334
0
      else
10335
0
        Prod = Iter;
10336
0
      Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
10337
10338
      // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10339
0
      auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10340
0
      DeclRefExpr *CounterVar = buildDeclRefExpr(
10341
0
          SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
10342
0
          /*RefersToCapture=*/true);
10343
0
      ExprResult Init =
10344
0
          buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
10345
0
                           IS.CounterInit, IS.IsNonRectangularLB, Captures);
10346
0
      if (!Init.isUsable()) {
10347
0
        HasErrors = true;
10348
0
        break;
10349
0
      }
10350
0
      ExprResult Update = buildCounterUpdate(
10351
0
          SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10352
0
          IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10353
0
      if (!Update.isUsable()) {
10354
0
        HasErrors = true;
10355
0
        break;
10356
0
      }
10357
10358
      // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10359
0
      ExprResult Final =
10360
0
          buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
10361
0
                             IS.CounterInit, IS.NumIterations, IS.CounterStep,
10362
0
                             IS.Subtract, IS.IsNonRectangularLB, &Captures);
10363
0
      if (!Final.isUsable()) {
10364
0
        HasErrors = true;
10365
0
        break;
10366
0
      }
10367
10368
0
      if (!Update.isUsable() || !Final.isUsable()) {
10369
0
        HasErrors = true;
10370
0
        break;
10371
0
      }
10372
      // Save results
10373
0
      Built.Counters[Cnt] = IS.CounterVar;
10374
0
      Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10375
0
      Built.Inits[Cnt] = Init.get();
10376
0
      Built.Updates[Cnt] = Update.get();
10377
0
      Built.Finals[Cnt] = Final.get();
10378
0
      Built.DependentCounters[Cnt] = nullptr;
10379
0
      Built.DependentInits[Cnt] = nullptr;
10380
0
      Built.FinalsConditions[Cnt] = nullptr;
10381
0
      if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10382
0
        Built.DependentCounters[Cnt] = Built.Counters[IS.LoopDependentIdx - 1];
10383
0
        Built.DependentInits[Cnt] = Built.Inits[IS.LoopDependentIdx - 1];
10384
0
        Built.FinalsConditions[Cnt] = IS.FinalCondition;
10385
0
      }
10386
0
    }
10387
0
  }
10388
10389
0
  if (HasErrors)
10390
0
    return 0;
10391
10392
  // Save results
10393
0
  Built.IterationVarRef = IV.get();
10394
0
  Built.LastIteration = LastIteration.get();
10395
0
  Built.NumIterations = NumIterations.get();
10396
0
  Built.CalcLastIteration = SemaRef
10397
0
                                .ActOnFinishFullExpr(CalcLastIteration.get(),
10398
0
                                                     /*DiscardedValue=*/false)
10399
0
                                .get();
10400
0
  Built.PreCond = PreCond.get();
10401
0
  Built.PreInits = buildPreInits(C, Captures);
10402
0
  Built.Cond = Cond.get();
10403
0
  Built.Init = Init.get();
10404
0
  Built.Inc = Inc.get();
10405
0
  Built.LB = LB.get();
10406
0
  Built.UB = UB.get();
10407
0
  Built.IL = IL.get();
10408
0
  Built.ST = ST.get();
10409
0
  Built.EUB = EUB.get();
10410
0
  Built.NLB = NextLB.get();
10411
0
  Built.NUB = NextUB.get();
10412
0
  Built.PrevLB = PrevLB.get();
10413
0
  Built.PrevUB = PrevUB.get();
10414
0
  Built.DistInc = DistInc.get();
10415
0
  Built.PrevEUB = PrevEUB.get();
10416
0
  Built.DistCombinedFields.LB = CombLB.get();
10417
0
  Built.DistCombinedFields.UB = CombUB.get();
10418
0
  Built.DistCombinedFields.EUB = CombEUB.get();
10419
0
  Built.DistCombinedFields.Init = CombInit.get();
10420
0
  Built.DistCombinedFields.Cond = CombCond.get();
10421
0
  Built.DistCombinedFields.NLB = CombNextLB.get();
10422
0
  Built.DistCombinedFields.NUB = CombNextUB.get();
10423
0
  Built.DistCombinedFields.DistCond = CombDistCond.get();
10424
0
  Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
10425
10426
0
  return NestedLoopCount;
10427
0
}
10428
10429
0
static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
10430
0
  auto CollapseClauses =
10431
0
      OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10432
0
  if (CollapseClauses.begin() != CollapseClauses.end())
10433
0
    return (*CollapseClauses.begin())->getNumForLoops();
10434
0
  return nullptr;
10435
0
}
10436
10437
0
static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
10438
0
  auto OrderedClauses =
10439
0
      OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10440
0
  if (OrderedClauses.begin() != OrderedClauses.end())
10441
0
    return (*OrderedClauses.begin())->getNumForLoops();
10442
0
  return nullptr;
10443
0
}
10444
10445
static bool checkSimdlenSafelenSpecified(Sema &S,
10446
0
                                         const ArrayRef<OMPClause *> Clauses) {
10447
0
  const OMPSafelenClause *Safelen = nullptr;
10448
0
  const OMPSimdlenClause *Simdlen = nullptr;
10449
10450
0
  for (const OMPClause *Clause : Clauses) {
10451
0
    if (Clause->getClauseKind() == OMPC_safelen)
10452
0
      Safelen = cast<OMPSafelenClause>(Clause);
10453
0
    else if (Clause->getClauseKind() == OMPC_simdlen)
10454
0
      Simdlen = cast<OMPSimdlenClause>(Clause);
10455
0
    if (Safelen && Simdlen)
10456
0
      break;
10457
0
  }
10458
10459
0
  if (Simdlen && Safelen) {
10460
0
    const Expr *SimdlenLength = Simdlen->getSimdlen();
10461
0
    const Expr *SafelenLength = Safelen->getSafelen();
10462
0
    if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
10463
0
        SimdlenLength->isInstantiationDependent() ||
10464
0
        SimdlenLength->containsUnexpandedParameterPack())
10465
0
      return false;
10466
0
    if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
10467
0
        SafelenLength->isInstantiationDependent() ||
10468
0
        SafelenLength->containsUnexpandedParameterPack())
10469
0
      return false;
10470
0
    Expr::EvalResult SimdlenResult, SafelenResult;
10471
0
    SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
10472
0
    SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
10473
0
    llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
10474
0
    llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
10475
    // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10476
    // If both simdlen and safelen clauses are specified, the value of the
10477
    // simdlen parameter must be less than or equal to the value of the safelen
10478
    // parameter.
10479
0
    if (SimdlenRes > SafelenRes) {
10480
0
      S.Diag(SimdlenLength->getExprLoc(),
10481
0
             diag::err_omp_wrong_simdlen_safelen_values)
10482
0
          << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
10483
0
      return true;
10484
0
    }
10485
0
  }
10486
0
  return false;
10487
0
}
10488
10489
static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10490
                                        OpenMPDirectiveKind K,
10491
                                        DSAStackTy *Stack);
10492
10493
0
bool Sema::checkLastPrivateForMappedDirectives(ArrayRef<OMPClause *> Clauses) {
10494
10495
  // Check for syntax of lastprivate
10496
  // Param of the lastprivate have different meanings in the mapped directives
10497
  // e.g. "omp loop" Only loop iteration vars are allowed in lastprivate clause
10498
  //      "omp for"  lastprivate vars must be shared
10499
0
  if (getLangOpts().OpenMP >= 50 &&
10500
0
      DSAStack->getMappedDirective() == OMPD_loop &&
10501
0
      checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) {
10502
0
    return false;
10503
0
  }
10504
0
  return true;
10505
0
}
10506
10507
StmtResult
10508
Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10509
                               SourceLocation StartLoc, SourceLocation EndLoc,
10510
0
                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10511
0
  if (!AStmt)
10512
0
    return StmtError();
10513
10514
0
  if (!checkLastPrivateForMappedDirectives(Clauses))
10515
0
    return StmtError();
10516
10517
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10518
0
  OMPLoopBasedDirective::HelperExprs B;
10519
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10520
  // define the nested loops number.
10521
0
  unsigned NestedLoopCount = checkOpenMPLoop(
10522
0
      OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10523
0
      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10524
0
  if (NestedLoopCount == 0)
10525
0
    return StmtError();
10526
10527
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10528
0
         "omp simd loop exprs were not built");
10529
10530
0
  if (!CurContext->isDependentContext()) {
10531
    // Finalize the clauses that need pre-built expressions for CodeGen.
10532
0
    for (OMPClause *C : Clauses) {
10533
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
10534
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10535
0
                                     B.NumIterations, *this, CurScope,
10536
0
                                     DSAStack))
10537
0
          return StmtError();
10538
0
    }
10539
0
  }
10540
10541
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
10542
0
    return StmtError();
10543
10544
0
  setFunctionHasBranchProtectedScope();
10545
0
  auto *SimdDirective = OMPSimdDirective::Create(
10546
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10547
0
      DSAStack->getMappedDirective());
10548
0
  return SimdDirective;
10549
0
}
10550
10551
StmtResult
10552
Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10553
                              SourceLocation StartLoc, SourceLocation EndLoc,
10554
0
                              VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10555
0
  if (!AStmt)
10556
0
    return StmtError();
10557
10558
0
  if (!checkLastPrivateForMappedDirectives(Clauses))
10559
0
    return StmtError();
10560
10561
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10562
0
  OMPLoopBasedDirective::HelperExprs B;
10563
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10564
  // define the nested loops number.
10565
0
  unsigned NestedLoopCount = checkOpenMPLoop(
10566
0
      OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10567
0
      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10568
0
  if (NestedLoopCount == 0)
10569
0
    return StmtError();
10570
10571
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10572
0
         "omp for loop exprs were not built");
10573
10574
0
  if (!CurContext->isDependentContext()) {
10575
    // Finalize the clauses that need pre-built expressions for CodeGen.
10576
0
    for (OMPClause *C : Clauses) {
10577
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
10578
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10579
0
                                     B.NumIterations, *this, CurScope,
10580
0
                                     DSAStack))
10581
0
          return StmtError();
10582
0
    }
10583
0
  }
10584
10585
0
  auto *ForDirective = OMPForDirective::Create(
10586
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10587
0
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion(),
10588
0
      DSAStack->getMappedDirective());
10589
0
  return ForDirective;
10590
0
}
10591
10592
StmtResult Sema::ActOnOpenMPForSimdDirective(
10593
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10594
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10595
0
  if (!AStmt)
10596
0
    return StmtError();
10597
10598
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10599
0
  OMPLoopBasedDirective::HelperExprs B;
10600
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10601
  // define the nested loops number.
10602
0
  unsigned NestedLoopCount =
10603
0
      checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10604
0
                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10605
0
                      VarsWithImplicitDSA, B);
10606
0
  if (NestedLoopCount == 0)
10607
0
    return StmtError();
10608
10609
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10610
0
         "omp for simd loop exprs were not built");
10611
10612
0
  if (!CurContext->isDependentContext()) {
10613
    // Finalize the clauses that need pre-built expressions for CodeGen.
10614
0
    for (OMPClause *C : Clauses) {
10615
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
10616
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10617
0
                                     B.NumIterations, *this, CurScope,
10618
0
                                     DSAStack))
10619
0
          return StmtError();
10620
0
    }
10621
0
  }
10622
10623
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
10624
0
    return StmtError();
10625
10626
0
  setFunctionHasBranchProtectedScope();
10627
0
  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10628
0
                                     Clauses, AStmt, B);
10629
0
}
10630
10631
StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10632
                                              Stmt *AStmt,
10633
                                              SourceLocation StartLoc,
10634
0
                                              SourceLocation EndLoc) {
10635
0
  if (!AStmt)
10636
0
    return StmtError();
10637
10638
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10639
0
  auto BaseStmt = AStmt;
10640
0
  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10641
0
    BaseStmt = CS->getCapturedStmt();
10642
0
  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10643
0
    auto S = C->children();
10644
0
    if (S.begin() == S.end())
10645
0
      return StmtError();
10646
    // All associated statements must be '#pragma omp section' except for
10647
    // the first one.
10648
0
    for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10649
0
      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10650
0
        if (SectionStmt)
10651
0
          Diag(SectionStmt->getBeginLoc(),
10652
0
               diag::err_omp_sections_substmt_not_section);
10653
0
        return StmtError();
10654
0
      }
10655
0
      cast<OMPSectionDirective>(SectionStmt)
10656
0
          ->setHasCancel(DSAStack->isCancelRegion());
10657
0
    }
10658
0
  } else {
10659
0
    Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10660
0
    return StmtError();
10661
0
  }
10662
10663
0
  setFunctionHasBranchProtectedScope();
10664
10665
0
  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10666
0
                                      DSAStack->getTaskgroupReductionRef(),
10667
0
                                      DSAStack->isCancelRegion());
10668
0
}
10669
10670
StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
10671
                                             SourceLocation StartLoc,
10672
0
                                             SourceLocation EndLoc) {
10673
0
  if (!AStmt)
10674
0
    return StmtError();
10675
10676
0
  setFunctionHasBranchProtectedScope();
10677
0
  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10678
10679
0
  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10680
0
                                     DSAStack->isCancelRegion());
10681
0
}
10682
10683
0
static Expr *getDirectCallExpr(Expr *E) {
10684
0
  E = E->IgnoreParenCasts()->IgnoreImplicit();
10685
0
  if (auto *CE = dyn_cast<CallExpr>(E))
10686
0
    if (CE->getDirectCallee())
10687
0
      return E;
10688
0
  return nullptr;
10689
0
}
10690
10691
StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10692
                                              Stmt *AStmt,
10693
                                              SourceLocation StartLoc,
10694
0
                                              SourceLocation EndLoc) {
10695
0
  if (!AStmt)
10696
0
    return StmtError();
10697
10698
0
  Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10699
10700
  // 5.1 OpenMP
10701
  // expression-stmt : an expression statement with one of the following forms:
10702
  //   expression = target-call ( [expression-list] );
10703
  //   target-call ( [expression-list] );
10704
10705
0
  SourceLocation TargetCallLoc;
10706
10707
0
  if (!CurContext->isDependentContext()) {
10708
0
    Expr *TargetCall = nullptr;
10709
10710
0
    auto *E = dyn_cast<Expr>(S);
10711
0
    if (!E) {
10712
0
      Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10713
0
      return StmtError();
10714
0
    }
10715
10716
0
    E = E->IgnoreParenCasts()->IgnoreImplicit();
10717
10718
0
    if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10719
0
      if (BO->getOpcode() == BO_Assign)
10720
0
        TargetCall = getDirectCallExpr(BO->getRHS());
10721
0
    } else {
10722
0
      if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10723
0
        if (COCE->getOperator() == OO_Equal)
10724
0
          TargetCall = getDirectCallExpr(COCE->getArg(1));
10725
0
      if (!TargetCall)
10726
0
        TargetCall = getDirectCallExpr(E);
10727
0
    }
10728
0
    if (!TargetCall) {
10729
0
      Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10730
0
      return StmtError();
10731
0
    }
10732
0
    TargetCallLoc = TargetCall->getExprLoc();
10733
0
  }
10734
10735
0
  setFunctionHasBranchProtectedScope();
10736
10737
0
  return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10738
0
                                      TargetCallLoc);
10739
0
}
10740
10741
static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10742
                                        OpenMPDirectiveKind K,
10743
0
                                        DSAStackTy *Stack) {
10744
0
  bool ErrorFound = false;
10745
0
  for (OMPClause *C : Clauses) {
10746
0
    if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10747
0
      for (Expr *RefExpr : LPC->varlists()) {
10748
0
        SourceLocation ELoc;
10749
0
        SourceRange ERange;
10750
0
        Expr *SimpleRefExpr = RefExpr;
10751
0
        auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10752
0
        if (ValueDecl *D = Res.first) {
10753
0
          auto &&Info = Stack->isLoopControlVariable(D);
10754
0
          if (!Info.first) {
10755
0
            S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10756
0
                << getOpenMPDirectiveName(K);
10757
0
            ErrorFound = true;
10758
0
          }
10759
0
        }
10760
0
      }
10761
0
    }
10762
0
  }
10763
0
  return ErrorFound;
10764
0
}
10765
10766
StmtResult Sema::ActOnOpenMPGenericLoopDirective(
10767
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10768
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10769
0
  if (!AStmt)
10770
0
    return StmtError();
10771
10772
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10773
  // A list item may not appear in a lastprivate clause unless it is the
10774
  // loop iteration variable of a loop that is associated with the construct.
10775
0
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack))
10776
0
    return StmtError();
10777
10778
0
  auto *CS = cast<CapturedStmt>(AStmt);
10779
  // 1.2.2 OpenMP Language Terminology
10780
  // Structured block - An executable statement with a single entry at the
10781
  // top and a single exit at the bottom.
10782
  // The point of exit cannot be a branch out of the structured block.
10783
  // longjmp() and throw() must not violate the entry/exit criteria.
10784
0
  CS->getCapturedDecl()->setNothrow();
10785
10786
0
  OMPLoopDirective::HelperExprs B;
10787
  // In presence of clause 'collapse', it will define the nested loops number.
10788
0
  unsigned NestedLoopCount = checkOpenMPLoop(
10789
0
      OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10790
0
      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10791
0
  if (NestedLoopCount == 0)
10792
0
    return StmtError();
10793
10794
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10795
0
         "omp loop exprs were not built");
10796
10797
0
  setFunctionHasBranchProtectedScope();
10798
0
  return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10799
0
                                         NestedLoopCount, Clauses, AStmt, B);
10800
0
}
10801
10802
StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective(
10803
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10804
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10805
0
  if (!AStmt)
10806
0
    return StmtError();
10807
10808
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10809
  // A list item may not appear in a lastprivate clause unless it is the
10810
  // loop iteration variable of a loop that is associated with the construct.
10811
0
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack))
10812
0
    return StmtError();
10813
10814
0
  auto *CS = cast<CapturedStmt>(AStmt);
10815
  // 1.2.2 OpenMP Language Terminology
10816
  // Structured block - An executable statement with a single entry at the
10817
  // top and a single exit at the bottom.
10818
  // The point of exit cannot be a branch out of the structured block.
10819
  // longjmp() and throw() must not violate the entry/exit criteria.
10820
0
  CS->getCapturedDecl()->setNothrow();
10821
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10822
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
10823
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
10824
    // 1.2.2 OpenMP Language Terminology
10825
    // Structured block - An executable statement with a single entry at the
10826
    // top and a single exit at the bottom.
10827
    // The point of exit cannot be a branch out of the structured block.
10828
    // longjmp() and throw() must not violate the entry/exit criteria.
10829
0
    CS->getCapturedDecl()->setNothrow();
10830
0
  }
10831
10832
0
  OMPLoopDirective::HelperExprs B;
10833
  // In presence of clause 'collapse', it will define the nested loops number.
10834
0
  unsigned NestedLoopCount =
10835
0
      checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10836
0
                      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10837
0
                      VarsWithImplicitDSA, B);
10838
0
  if (NestedLoopCount == 0)
10839
0
    return StmtError();
10840
10841
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10842
0
         "omp loop exprs were not built");
10843
10844
0
  setFunctionHasBranchProtectedScope();
10845
0
  DSAStack->setParentTeamsRegionLoc(StartLoc);
10846
10847
0
  return OMPTeamsGenericLoopDirective::Create(
10848
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10849
0
}
10850
10851
StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective(
10852
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10853
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10854
0
  if (!AStmt)
10855
0
    return StmtError();
10856
10857
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10858
  // A list item may not appear in a lastprivate clause unless it is the
10859
  // loop iteration variable of a loop that is associated with the construct.
10860
0
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10861
0
                                  DSAStack))
10862
0
    return StmtError();
10863
10864
0
  auto *CS = cast<CapturedStmt>(AStmt);
10865
  // 1.2.2 OpenMP Language Terminology
10866
  // Structured block - An executable statement with a single entry at the
10867
  // top and a single exit at the bottom.
10868
  // The point of exit cannot be a branch out of the structured block.
10869
  // longjmp() and throw() must not violate the entry/exit criteria.
10870
0
  CS->getCapturedDecl()->setNothrow();
10871
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10872
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
10873
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
10874
    // 1.2.2 OpenMP Language Terminology
10875
    // Structured block - An executable statement with a single entry at the
10876
    // top and a single exit at the bottom.
10877
    // The point of exit cannot be a branch out of the structured block.
10878
    // longjmp() and throw() must not violate the entry/exit criteria.
10879
0
    CS->getCapturedDecl()->setNothrow();
10880
0
  }
10881
10882
0
  OMPLoopDirective::HelperExprs B;
10883
  // In presence of clause 'collapse', it will define the nested loops number.
10884
0
  unsigned NestedLoopCount =
10885
0
      checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10886
0
                      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10887
0
                      VarsWithImplicitDSA, B);
10888
0
  if (NestedLoopCount == 0)
10889
0
    return StmtError();
10890
10891
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10892
0
         "omp loop exprs were not built");
10893
10894
0
  setFunctionHasBranchProtectedScope();
10895
10896
0
  return OMPTargetTeamsGenericLoopDirective::Create(
10897
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10898
0
}
10899
10900
StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective(
10901
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10902
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10903
0
  if (!AStmt)
10904
0
    return StmtError();
10905
10906
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10907
  // A list item may not appear in a lastprivate clause unless it is the
10908
  // loop iteration variable of a loop that is associated with the construct.
10909
0
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack))
10910
0
    return StmtError();
10911
10912
0
  auto *CS = cast<CapturedStmt>(AStmt);
10913
  // 1.2.2 OpenMP Language Terminology
10914
  // Structured block - An executable statement with a single entry at the
10915
  // top and a single exit at the bottom.
10916
  // The point of exit cannot be a branch out of the structured block.
10917
  // longjmp() and throw() must not violate the entry/exit criteria.
10918
0
  CS->getCapturedDecl()->setNothrow();
10919
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10920
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
10921
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
10922
    // 1.2.2 OpenMP Language Terminology
10923
    // Structured block - An executable statement with a single entry at the
10924
    // top and a single exit at the bottom.
10925
    // The point of exit cannot be a branch out of the structured block.
10926
    // longjmp() and throw() must not violate the entry/exit criteria.
10927
0
    CS->getCapturedDecl()->setNothrow();
10928
0
  }
10929
10930
0
  OMPLoopDirective::HelperExprs B;
10931
  // In presence of clause 'collapse', it will define the nested loops number.
10932
0
  unsigned NestedLoopCount =
10933
0
      checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10934
0
                      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10935
0
                      VarsWithImplicitDSA, B);
10936
0
  if (NestedLoopCount == 0)
10937
0
    return StmtError();
10938
10939
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10940
0
         "omp loop exprs were not built");
10941
10942
0
  setFunctionHasBranchProtectedScope();
10943
10944
0
  return OMPParallelGenericLoopDirective::Create(
10945
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10946
0
}
10947
10948
StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective(
10949
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10950
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10951
0
  if (!AStmt)
10952
0
    return StmtError();
10953
10954
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10955
  // A list item may not appear in a lastprivate clause unless it is the
10956
  // loop iteration variable of a loop that is associated with the construct.
10957
0
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10958
0
                                  DSAStack))
10959
0
    return StmtError();
10960
10961
0
  auto *CS = cast<CapturedStmt>(AStmt);
10962
  // 1.2.2 OpenMP Language Terminology
10963
  // Structured block - An executable statement with a single entry at the
10964
  // top and a single exit at the bottom.
10965
  // The point of exit cannot be a branch out of the structured block.
10966
  // longjmp() and throw() must not violate the entry/exit criteria.
10967
0
  CS->getCapturedDecl()->setNothrow();
10968
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10969
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
10970
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
10971
    // 1.2.2 OpenMP Language Terminology
10972
    // Structured block - An executable statement with a single entry at the
10973
    // top and a single exit at the bottom.
10974
    // The point of exit cannot be a branch out of the structured block.
10975
    // longjmp() and throw() must not violate the entry/exit criteria.
10976
0
    CS->getCapturedDecl()->setNothrow();
10977
0
  }
10978
10979
0
  OMPLoopDirective::HelperExprs B;
10980
  // In presence of clause 'collapse', it will define the nested loops number.
10981
0
  unsigned NestedLoopCount =
10982
0
      checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10983
0
                      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10984
0
                      VarsWithImplicitDSA, B);
10985
0
  if (NestedLoopCount == 0)
10986
0
    return StmtError();
10987
10988
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10989
0
         "omp loop exprs were not built");
10990
10991
0
  setFunctionHasBranchProtectedScope();
10992
10993
0
  return OMPTargetParallelGenericLoopDirective::Create(
10994
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10995
0
}
10996
10997
StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10998
                                            Stmt *AStmt,
10999
                                            SourceLocation StartLoc,
11000
0
                                            SourceLocation EndLoc) {
11001
0
  if (!AStmt)
11002
0
    return StmtError();
11003
11004
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11005
11006
0
  setFunctionHasBranchProtectedScope();
11007
11008
  // OpenMP [2.7.3, single Construct, Restrictions]
11009
  // The copyprivate clause must not be used with the nowait clause.
11010
0
  const OMPClause *Nowait = nullptr;
11011
0
  const OMPClause *Copyprivate = nullptr;
11012
0
  for (const OMPClause *Clause : Clauses) {
11013
0
    if (Clause->getClauseKind() == OMPC_nowait)
11014
0
      Nowait = Clause;
11015
0
    else if (Clause->getClauseKind() == OMPC_copyprivate)
11016
0
      Copyprivate = Clause;
11017
0
    if (Copyprivate && Nowait) {
11018
0
      Diag(Copyprivate->getBeginLoc(),
11019
0
           diag::err_omp_single_copyprivate_with_nowait);
11020
0
      Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
11021
0
      return StmtError();
11022
0
    }
11023
0
  }
11024
11025
0
  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11026
0
}
11027
11028
StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
11029
                                            SourceLocation StartLoc,
11030
0
                                            SourceLocation EndLoc) {
11031
0
  if (!AStmt)
11032
0
    return StmtError();
11033
11034
0
  setFunctionHasBranchProtectedScope();
11035
11036
0
  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
11037
0
}
11038
11039
StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
11040
                                            Stmt *AStmt,
11041
                                            SourceLocation StartLoc,
11042
0
                                            SourceLocation EndLoc) {
11043
0
  if (!AStmt)
11044
0
    return StmtError();
11045
11046
0
  setFunctionHasBranchProtectedScope();
11047
11048
0
  return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11049
0
}
11050
11051
StmtResult Sema::ActOnOpenMPCriticalDirective(
11052
    const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
11053
0
    Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
11054
0
  if (!AStmt)
11055
0
    return StmtError();
11056
11057
0
  bool ErrorFound = false;
11058
0
  llvm::APSInt Hint;
11059
0
  SourceLocation HintLoc;
11060
0
  bool DependentHint = false;
11061
0
  for (const OMPClause *C : Clauses) {
11062
0
    if (C->getClauseKind() == OMPC_hint) {
11063
0
      if (!DirName.getName()) {
11064
0
        Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
11065
0
        ErrorFound = true;
11066
0
      }
11067
0
      Expr *E = cast<OMPHintClause>(C)->getHint();
11068
0
      if (E->isTypeDependent() || E->isValueDependent() ||
11069
0
          E->isInstantiationDependent()) {
11070
0
        DependentHint = true;
11071
0
      } else {
11072
0
        Hint = E->EvaluateKnownConstInt(Context);
11073
0
        HintLoc = C->getBeginLoc();
11074
0
      }
11075
0
    }
11076
0
  }
11077
0
  if (ErrorFound)
11078
0
    return StmtError();
11079
0
  const auto Pair = DSAStack->getCriticalWithHint(DirName);
11080
0
  if (Pair.first && DirName.getName() && !DependentHint) {
11081
0
    if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
11082
0
      Diag(StartLoc, diag::err_omp_critical_with_hint);
11083
0
      if (HintLoc.isValid())
11084
0
        Diag(HintLoc, diag::note_omp_critical_hint_here)
11085
0
            << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
11086
0
      else
11087
0
        Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
11088
0
      if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
11089
0
        Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
11090
0
            << 1
11091
0
            << toString(C->getHint()->EvaluateKnownConstInt(Context),
11092
0
                        /*Radix=*/10, /*Signed=*/false);
11093
0
      } else {
11094
0
        Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
11095
0
      }
11096
0
    }
11097
0
  }
11098
11099
0
  setFunctionHasBranchProtectedScope();
11100
11101
0
  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
11102
0
                                           Clauses, AStmt);
11103
0
  if (!Pair.first && DirName.getName() && !DependentHint)
11104
0
    DSAStack->addCriticalWithHint(Dir, Hint);
11105
0
  return Dir;
11106
0
}
11107
11108
StmtResult Sema::ActOnOpenMPParallelForDirective(
11109
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11110
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11111
0
  if (!AStmt)
11112
0
    return StmtError();
11113
11114
0
  auto *CS = cast<CapturedStmt>(AStmt);
11115
  // 1.2.2 OpenMP Language Terminology
11116
  // Structured block - An executable statement with a single entry at the
11117
  // top and a single exit at the bottom.
11118
  // The point of exit cannot be a branch out of the structured block.
11119
  // longjmp() and throw() must not violate the entry/exit criteria.
11120
0
  CS->getCapturedDecl()->setNothrow();
11121
11122
0
  OMPLoopBasedDirective::HelperExprs B;
11123
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11124
  // define the nested loops number.
11125
0
  unsigned NestedLoopCount =
11126
0
      checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
11127
0
                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
11128
0
                      VarsWithImplicitDSA, B);
11129
0
  if (NestedLoopCount == 0)
11130
0
    return StmtError();
11131
11132
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
11133
0
         "omp parallel for loop exprs were not built");
11134
11135
0
  if (!CurContext->isDependentContext()) {
11136
    // Finalize the clauses that need pre-built expressions for CodeGen.
11137
0
    for (OMPClause *C : Clauses) {
11138
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
11139
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11140
0
                                     B.NumIterations, *this, CurScope,
11141
0
                                     DSAStack))
11142
0
          return StmtError();
11143
0
    }
11144
0
  }
11145
11146
0
  setFunctionHasBranchProtectedScope();
11147
0
  return OMPParallelForDirective::Create(
11148
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11149
0
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11150
0
}
11151
11152
StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
11153
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11154
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11155
0
  if (!AStmt)
11156
0
    return StmtError();
11157
11158
0
  auto *CS = cast<CapturedStmt>(AStmt);
11159
  // 1.2.2 OpenMP Language Terminology
11160
  // Structured block - An executable statement with a single entry at the
11161
  // top and a single exit at the bottom.
11162
  // The point of exit cannot be a branch out of the structured block.
11163
  // longjmp() and throw() must not violate the entry/exit criteria.
11164
0
  CS->getCapturedDecl()->setNothrow();
11165
11166
0
  OMPLoopBasedDirective::HelperExprs B;
11167
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11168
  // define the nested loops number.
11169
0
  unsigned NestedLoopCount =
11170
0
      checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
11171
0
                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
11172
0
                      VarsWithImplicitDSA, B);
11173
0
  if (NestedLoopCount == 0)
11174
0
    return StmtError();
11175
11176
0
  if (!CurContext->isDependentContext()) {
11177
    // Finalize the clauses that need pre-built expressions for CodeGen.
11178
0
    for (OMPClause *C : Clauses) {
11179
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
11180
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11181
0
                                     B.NumIterations, *this, CurScope,
11182
0
                                     DSAStack))
11183
0
          return StmtError();
11184
0
    }
11185
0
  }
11186
11187
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
11188
0
    return StmtError();
11189
11190
0
  setFunctionHasBranchProtectedScope();
11191
0
  return OMPParallelForSimdDirective::Create(
11192
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11193
0
}
11194
11195
StmtResult
11196
Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
11197
                                         Stmt *AStmt, SourceLocation StartLoc,
11198
0
                                         SourceLocation EndLoc) {
11199
0
  if (!AStmt)
11200
0
    return StmtError();
11201
11202
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11203
0
  auto *CS = cast<CapturedStmt>(AStmt);
11204
  // 1.2.2 OpenMP Language Terminology
11205
  // Structured block - An executable statement with a single entry at the
11206
  // top and a single exit at the bottom.
11207
  // The point of exit cannot be a branch out of the structured block.
11208
  // longjmp() and throw() must not violate the entry/exit criteria.
11209
0
  CS->getCapturedDecl()->setNothrow();
11210
11211
0
  setFunctionHasBranchProtectedScope();
11212
11213
0
  return OMPParallelMasterDirective::Create(
11214
0
      Context, StartLoc, EndLoc, Clauses, AStmt,
11215
0
      DSAStack->getTaskgroupReductionRef());
11216
0
}
11217
11218
StmtResult
11219
Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses,
11220
                                         Stmt *AStmt, SourceLocation StartLoc,
11221
0
                                         SourceLocation EndLoc) {
11222
0
  if (!AStmt)
11223
0
    return StmtError();
11224
11225
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11226
0
  auto *CS = cast<CapturedStmt>(AStmt);
11227
  // 1.2.2 OpenMP Language Terminology
11228
  // Structured block - An executable statement with a single entry at the
11229
  // top and a single exit at the bottom.
11230
  // The point of exit cannot be a branch out of the structured block.
11231
  // longjmp() and throw() must not violate the entry/exit criteria.
11232
0
  CS->getCapturedDecl()->setNothrow();
11233
11234
0
  setFunctionHasBranchProtectedScope();
11235
11236
0
  return OMPParallelMaskedDirective::Create(
11237
0
      Context, StartLoc, EndLoc, Clauses, AStmt,
11238
0
      DSAStack->getTaskgroupReductionRef());
11239
0
}
11240
11241
StmtResult
11242
Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
11243
                                           Stmt *AStmt, SourceLocation StartLoc,
11244
0
                                           SourceLocation EndLoc) {
11245
0
  if (!AStmt)
11246
0
    return StmtError();
11247
11248
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11249
0
  auto BaseStmt = AStmt;
11250
0
  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
11251
0
    BaseStmt = CS->getCapturedStmt();
11252
0
  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
11253
0
    auto S = C->children();
11254
0
    if (S.begin() == S.end())
11255
0
      return StmtError();
11256
    // All associated statements must be '#pragma omp section' except for
11257
    // the first one.
11258
0
    for (Stmt *SectionStmt : llvm::drop_begin(S)) {
11259
0
      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
11260
0
        if (SectionStmt)
11261
0
          Diag(SectionStmt->getBeginLoc(),
11262
0
               diag::err_omp_parallel_sections_substmt_not_section);
11263
0
        return StmtError();
11264
0
      }
11265
0
      cast<OMPSectionDirective>(SectionStmt)
11266
0
          ->setHasCancel(DSAStack->isCancelRegion());
11267
0
    }
11268
0
  } else {
11269
0
    Diag(AStmt->getBeginLoc(),
11270
0
         diag::err_omp_parallel_sections_not_compound_stmt);
11271
0
    return StmtError();
11272
0
  }
11273
11274
0
  setFunctionHasBranchProtectedScope();
11275
11276
0
  return OMPParallelSectionsDirective::Create(
11277
0
      Context, StartLoc, EndLoc, Clauses, AStmt,
11278
0
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11279
0
}
11280
11281
/// Find and diagnose mutually exclusive clause kinds.
11282
static bool checkMutuallyExclusiveClauses(
11283
    Sema &S, ArrayRef<OMPClause *> Clauses,
11284
0
    ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
11285
0
  const OMPClause *PrevClause = nullptr;
11286
0
  bool ErrorFound = false;
11287
0
  for (const OMPClause *C : Clauses) {
11288
0
    if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
11289
0
      if (!PrevClause) {
11290
0
        PrevClause = C;
11291
0
      } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
11292
0
        S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11293
0
            << getOpenMPClauseName(C->getClauseKind())
11294
0
            << getOpenMPClauseName(PrevClause->getClauseKind());
11295
0
        S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11296
0
            << getOpenMPClauseName(PrevClause->getClauseKind());
11297
0
        ErrorFound = true;
11298
0
      }
11299
0
    }
11300
0
  }
11301
0
  return ErrorFound;
11302
0
}
11303
11304
StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
11305
                                          Stmt *AStmt, SourceLocation StartLoc,
11306
0
                                          SourceLocation EndLoc) {
11307
0
  if (!AStmt)
11308
0
    return StmtError();
11309
11310
  // OpenMP 5.0, 2.10.1 task Construct
11311
  // If a detach clause appears on the directive, then a mergeable clause cannot
11312
  // appear on the same directive.
11313
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
11314
0
                                    {OMPC_detach, OMPC_mergeable}))
11315
0
    return StmtError();
11316
11317
0
  auto *CS = cast<CapturedStmt>(AStmt);
11318
  // 1.2.2 OpenMP Language Terminology
11319
  // Structured block - An executable statement with a single entry at the
11320
  // top and a single exit at the bottom.
11321
  // The point of exit cannot be a branch out of the structured block.
11322
  // longjmp() and throw() must not violate the entry/exit criteria.
11323
0
  CS->getCapturedDecl()->setNothrow();
11324
11325
0
  setFunctionHasBranchProtectedScope();
11326
11327
0
  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11328
0
                                  DSAStack->isCancelRegion());
11329
0
}
11330
11331
StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
11332
0
                                               SourceLocation EndLoc) {
11333
0
  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
11334
0
}
11335
11336
StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
11337
0
                                             SourceLocation EndLoc) {
11338
0
  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
11339
0
}
11340
11341
StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
11342
                                           SourceLocation StartLoc,
11343
                                           SourceLocation EndLoc,
11344
0
                                           bool InExContext) {
11345
0
  const OMPAtClause *AtC =
11346
0
      OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11347
11348
0
  if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) {
11349
0
    Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
11350
0
    return StmtError();
11351
0
  }
11352
11353
0
  const OMPSeverityClause *SeverityC =
11354
0
      OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11355
0
  const OMPMessageClause *MessageC =
11356
0
      OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11357
0
  Expr *ME = MessageC ? MessageC->getMessageString() : nullptr;
11358
11359
0
  if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
11360
0
    if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
11361
0
      Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
11362
0
          << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING");
11363
0
    else
11364
0
      Diag(StartLoc, diag::err_diagnose_if_succeeded)
11365
0
          << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR");
11366
0
    if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
11367
0
      return StmtError();
11368
0
  }
11369
0
  return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
11370
0
}
11371
11372
StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
11373
                                              SourceLocation StartLoc,
11374
0
                                              SourceLocation EndLoc) {
11375
0
  const OMPNowaitClause *NowaitC =
11376
0
      OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11377
0
  bool HasDependC =
11378
0
      !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11379
0
           .empty();
11380
0
  if (NowaitC && !HasDependC) {
11381
0
    Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11382
0
    return StmtError();
11383
0
  }
11384
11385
0
  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
11386
0
}
11387
11388
StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
11389
                                               Stmt *AStmt,
11390
                                               SourceLocation StartLoc,
11391
0
                                               SourceLocation EndLoc) {
11392
0
  if (!AStmt)
11393
0
    return StmtError();
11394
11395
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11396
11397
0
  setFunctionHasBranchProtectedScope();
11398
11399
0
  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
11400
0
                                       AStmt,
11401
0
                                       DSAStack->getTaskgroupReductionRef());
11402
0
}
11403
11404
StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
11405
                                           SourceLocation StartLoc,
11406
0
                                           SourceLocation EndLoc) {
11407
0
  OMPFlushClause *FC = nullptr;
11408
0
  OMPClause *OrderClause = nullptr;
11409
0
  for (OMPClause *C : Clauses) {
11410
0
    if (C->getClauseKind() == OMPC_flush)
11411
0
      FC = cast<OMPFlushClause>(C);
11412
0
    else
11413
0
      OrderClause = C;
11414
0
  }
11415
0
  OpenMPClauseKind MemOrderKind = OMPC_unknown;
11416
0
  SourceLocation MemOrderLoc;
11417
0
  for (const OMPClause *C : Clauses) {
11418
0
    if (C->getClauseKind() == OMPC_acq_rel ||
11419
0
        C->getClauseKind() == OMPC_acquire ||
11420
0
        C->getClauseKind() == OMPC_release) {
11421
0
      if (MemOrderKind != OMPC_unknown) {
11422
0
        Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11423
0
            << getOpenMPDirectiveName(OMPD_flush) << 1
11424
0
            << SourceRange(C->getBeginLoc(), C->getEndLoc());
11425
0
        Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11426
0
            << getOpenMPClauseName(MemOrderKind);
11427
0
      } else {
11428
0
        MemOrderKind = C->getClauseKind();
11429
0
        MemOrderLoc = C->getBeginLoc();
11430
0
      }
11431
0
    }
11432
0
  }
11433
0
  if (FC && OrderClause) {
11434
0
    Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
11435
0
        << getOpenMPClauseName(OrderClause->getClauseKind());
11436
0
    Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
11437
0
        << getOpenMPClauseName(OrderClause->getClauseKind());
11438
0
    return StmtError();
11439
0
  }
11440
0
  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
11441
0
}
11442
11443
StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
11444
                                            SourceLocation StartLoc,
11445
0
                                            SourceLocation EndLoc) {
11446
0
  if (Clauses.empty()) {
11447
0
    Diag(StartLoc, diag::err_omp_depobj_expected);
11448
0
    return StmtError();
11449
0
  } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11450
0
    Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11451
0
    return StmtError();
11452
0
  }
11453
  // Only depobj expression and another single clause is allowed.
11454
0
  if (Clauses.size() > 2) {
11455
0
    Diag(Clauses[2]->getBeginLoc(),
11456
0
         diag::err_omp_depobj_single_clause_expected);
11457
0
    return StmtError();
11458
0
  } else if (Clauses.size() < 1) {
11459
0
    Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11460
0
    return StmtError();
11461
0
  }
11462
0
  return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
11463
0
}
11464
11465
StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
11466
                                          SourceLocation StartLoc,
11467
0
                                          SourceLocation EndLoc) {
11468
  // Check that exactly one clause is specified.
11469
0
  if (Clauses.size() != 1) {
11470
0
    Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11471
0
         diag::err_omp_scan_single_clause_expected);
11472
0
    return StmtError();
11473
0
  }
11474
  // Check that scan directive is used in the scopeof the OpenMP loop body.
11475
0
  if (Scope *S = DSAStack->getCurScope()) {
11476
0
    Scope *ParentS = S->getParent();
11477
0
    if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
11478
0
        !ParentS->getBreakParent()->isOpenMPLoopScope())
11479
0
      return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11480
0
                       << getOpenMPDirectiveName(OMPD_scan) << 5);
11481
0
  }
11482
  // Check that only one instance of scan directives is used in the same outer
11483
  // region.
11484
0
  if (DSAStack->doesParentHasScanDirective()) {
11485
0
    Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
11486
0
    Diag(DSAStack->getParentScanDirectiveLoc(),
11487
0
         diag::note_omp_previous_directive)
11488
0
        << "scan";
11489
0
    return StmtError();
11490
0
  }
11491
0
  DSAStack->setParentHasScanDirective(StartLoc);
11492
0
  return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
11493
0
}
11494
11495
StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
11496
                                             Stmt *AStmt,
11497
                                             SourceLocation StartLoc,
11498
0
                                             SourceLocation EndLoc) {
11499
0
  const OMPClause *DependFound = nullptr;
11500
0
  const OMPClause *DependSourceClause = nullptr;
11501
0
  const OMPClause *DependSinkClause = nullptr;
11502
0
  const OMPClause *DoacrossFound = nullptr;
11503
0
  const OMPClause *DoacrossSourceClause = nullptr;
11504
0
  const OMPClause *DoacrossSinkClause = nullptr;
11505
0
  bool ErrorFound = false;
11506
0
  const OMPThreadsClause *TC = nullptr;
11507
0
  const OMPSIMDClause *SC = nullptr;
11508
0
  for (const OMPClause *C : Clauses) {
11509
0
    auto DOC = dyn_cast<OMPDoacrossClause>(C);
11510
0
    auto DC = dyn_cast<OMPDependClause>(C);
11511
0
    if (DC || DOC) {
11512
0
      DependFound = DC ? C : nullptr;
11513
0
      DoacrossFound = DOC ? C : nullptr;
11514
0
      OMPDoacrossKind ODK;
11515
0
      if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) ||
11516
0
          (DOC && (ODK.isSource(DOC)))) {
11517
0
        if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
11518
0
          Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
11519
0
              << getOpenMPDirectiveName(OMPD_ordered)
11520
0
              << getOpenMPClauseName(DC ? OMPC_depend : OMPC_doacross) << 2;
11521
0
          ErrorFound = true;
11522
0
        } else {
11523
0
          if (DC)
11524
0
            DependSourceClause = C;
11525
0
          else
11526
0
            DoacrossSourceClause = C;
11527
0
        }
11528
0
        if ((DC && DependSinkClause) || (DOC && DoacrossSinkClause)) {
11529
0
          Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11530
0
              << (DC ? "depend" : "doacross") << 0;
11531
0
          ErrorFound = true;
11532
0
        }
11533
0
      } else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) ||
11534
0
                 (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) {
11535
0
        if (DependSourceClause || DoacrossSourceClause) {
11536
0
          Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11537
0
              << (DC ? "depend" : "doacross") << 1;
11538
0
          ErrorFound = true;
11539
0
        }
11540
0
        if (DC)
11541
0
          DependSinkClause = C;
11542
0
        else
11543
0
          DoacrossSinkClause = C;
11544
0
      }
11545
0
    } else if (C->getClauseKind() == OMPC_threads) {
11546
0
      TC = cast<OMPThreadsClause>(C);
11547
0
    } else if (C->getClauseKind() == OMPC_simd) {
11548
0
      SC = cast<OMPSIMDClause>(C);
11549
0
    }
11550
0
  }
11551
0
  if (!ErrorFound && !SC &&
11552
0
      isOpenMPSimdDirective(DSAStack->getParentDirective())) {
11553
    // OpenMP [2.8.1,simd Construct, Restrictions]
11554
    // An ordered construct with the simd clause is the only OpenMP construct
11555
    // that can appear in the simd region.
11556
0
    Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11557
0
        << (LangOpts.OpenMP >= 50 ? 1 : 0);
11558
0
    ErrorFound = true;
11559
0
  } else if ((DependFound || DoacrossFound) && (TC || SC)) {
11560
0
    SourceLocation Loc =
11561
0
        DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11562
0
    Diag(Loc, diag::err_omp_depend_clause_thread_simd)
11563
0
        << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross)
11564
0
        << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
11565
0
    ErrorFound = true;
11566
0
  } else if ((DependFound || DoacrossFound) &&
11567
0
             !DSAStack->getParentOrderedRegionParam().first) {
11568
0
    SourceLocation Loc =
11569
0
        DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11570
0
    Diag(Loc, diag::err_omp_ordered_directive_without_param)
11571
0
        << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross);
11572
0
    ErrorFound = true;
11573
0
  } else if (TC || Clauses.empty()) {
11574
0
    if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
11575
0
      SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
11576
0
      Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11577
0
          << (TC != nullptr);
11578
0
      Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11579
0
      ErrorFound = true;
11580
0
    }
11581
0
  }
11582
0
  if ((!AStmt && !DependFound && !DoacrossFound) || ErrorFound)
11583
0
    return StmtError();
11584
11585
  // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11586
  // During execution of an iteration of a worksharing-loop or a loop nest
11587
  // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11588
  // must not execute more than one ordered region corresponding to an ordered
11589
  // construct without a depend clause.
11590
0
  if (!DependFound && !DoacrossFound) {
11591
0
    if (DSAStack->doesParentHasOrderedDirective()) {
11592
0
      Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
11593
0
      Diag(DSAStack->getParentOrderedDirectiveLoc(),
11594
0
           diag::note_omp_previous_directive)
11595
0
          << "ordered";
11596
0
      return StmtError();
11597
0
    }
11598
0
    DSAStack->setParentHasOrderedDirective(StartLoc);
11599
0
  }
11600
11601
0
  if (AStmt) {
11602
0
    assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11603
11604
0
    setFunctionHasBranchProtectedScope();
11605
0
  }
11606
11607
0
  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11608
0
}
11609
11610
namespace {
11611
/// Helper class for checking expression in 'omp atomic [update]'
11612
/// construct.
11613
class OpenMPAtomicUpdateChecker {
11614
  /// Error results for atomic update expressions.
11615
  enum ExprAnalysisErrorCode {
11616
    /// A statement is not an expression statement.
11617
    NotAnExpression,
11618
    /// Expression is not builtin binary or unary operation.
11619
    NotABinaryOrUnaryExpression,
11620
    /// Unary operation is not post-/pre- increment/decrement operation.
11621
    NotAnUnaryIncDecExpression,
11622
    /// An expression is not of scalar type.
11623
    NotAScalarType,
11624
    /// A binary operation is not an assignment operation.
11625
    NotAnAssignmentOp,
11626
    /// RHS part of the binary operation is not a binary expression.
11627
    NotABinaryExpression,
11628
    /// RHS part is not additive/multiplicative/shift/biwise binary
11629
    /// expression.
11630
    NotABinaryOperator,
11631
    /// RHS binary operation does not have reference to the updated LHS
11632
    /// part.
11633
    NotAnUpdateExpression,
11634
    /// An expression contains semantical error not related to
11635
    /// 'omp atomic [update]'
11636
    NotAValidExpression,
11637
    /// No errors is found.
11638
    NoError
11639
  };
11640
  /// Reference to Sema.
11641
  Sema &SemaRef;
11642
  /// A location for note diagnostics (when error is found).
11643
  SourceLocation NoteLoc;
11644
  /// 'x' lvalue part of the source atomic expression.
11645
  Expr *X;
11646
  /// 'expr' rvalue part of the source atomic expression.
11647
  Expr *E;
11648
  /// Helper expression of the form
11649
  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11650
  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11651
  Expr *UpdateExpr;
11652
  /// Is 'x' a LHS in a RHS part of full update expression. It is
11653
  /// important for non-associative operations.
11654
  bool IsXLHSInRHSPart;
11655
  BinaryOperatorKind Op;
11656
  SourceLocation OpLoc;
11657
  /// true if the source expression is a postfix unary operation, false
11658
  /// if it is a prefix unary operation.
11659
  bool IsPostfixUpdate;
11660
11661
public:
11662
  OpenMPAtomicUpdateChecker(Sema &SemaRef)
11663
      : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11664
0
        IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11665
  /// Check specified statement that it is suitable for 'atomic update'
11666
  /// constructs and extract 'x', 'expr' and Operation from the original
11667
  /// expression. If DiagId and NoteId == 0, then only check is performed
11668
  /// without error notification.
11669
  /// \param DiagId Diagnostic which should be emitted if error is found.
11670
  /// \param NoteId Diagnostic note for the main error message.
11671
  /// \return true if statement is not an update expression, false otherwise.
11672
  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11673
  /// Return the 'x' lvalue part of the source atomic expression.
11674
0
  Expr *getX() const { return X; }
11675
  /// Return the 'expr' rvalue part of the source atomic expression.
11676
0
  Expr *getExpr() const { return E; }
11677
  /// Return the update expression used in calculation of the updated
11678
  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11679
  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11680
0
  Expr *getUpdateExpr() const { return UpdateExpr; }
11681
  /// Return true if 'x' is LHS in RHS part of full update expression,
11682
  /// false otherwise.
11683
0
  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11684
11685
  /// true if the source expression is a postfix unary operation, false
11686
  /// if it is a prefix unary operation.
11687
0
  bool isPostfixUpdate() const { return IsPostfixUpdate; }
11688
11689
private:
11690
  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11691
                            unsigned NoteId = 0);
11692
};
11693
11694
bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11695
0
    BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11696
0
  ExprAnalysisErrorCode ErrorFound = NoError;
11697
0
  SourceLocation ErrorLoc, NoteLoc;
11698
0
  SourceRange ErrorRange, NoteRange;
11699
  // Allowed constructs are:
11700
  //  x = x binop expr;
11701
  //  x = expr binop x;
11702
0
  if (AtomicBinOp->getOpcode() == BO_Assign) {
11703
0
    X = AtomicBinOp->getLHS();
11704
0
    if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11705
0
            AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11706
0
      if (AtomicInnerBinOp->isMultiplicativeOp() ||
11707
0
          AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11708
0
          AtomicInnerBinOp->isBitwiseOp()) {
11709
0
        Op = AtomicInnerBinOp->getOpcode();
11710
0
        OpLoc = AtomicInnerBinOp->getOperatorLoc();
11711
0
        Expr *LHS = AtomicInnerBinOp->getLHS();
11712
0
        Expr *RHS = AtomicInnerBinOp->getRHS();
11713
0
        llvm::FoldingSetNodeID XId, LHSId, RHSId;
11714
0
        X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11715
0
                                          /*Canonical=*/true);
11716
0
        LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11717
0
                                            /*Canonical=*/true);
11718
0
        RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11719
0
                                            /*Canonical=*/true);
11720
0
        if (XId == LHSId) {
11721
0
          E = RHS;
11722
0
          IsXLHSInRHSPart = true;
11723
0
        } else if (XId == RHSId) {
11724
0
          E = LHS;
11725
0
          IsXLHSInRHSPart = false;
11726
0
        } else {
11727
0
          ErrorLoc = AtomicInnerBinOp->getExprLoc();
11728
0
          ErrorRange = AtomicInnerBinOp->getSourceRange();
11729
0
          NoteLoc = X->getExprLoc();
11730
0
          NoteRange = X->getSourceRange();
11731
0
          ErrorFound = NotAnUpdateExpression;
11732
0
        }
11733
0
      } else {
11734
0
        ErrorLoc = AtomicInnerBinOp->getExprLoc();
11735
0
        ErrorRange = AtomicInnerBinOp->getSourceRange();
11736
0
        NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11737
0
        NoteRange = SourceRange(NoteLoc, NoteLoc);
11738
0
        ErrorFound = NotABinaryOperator;
11739
0
      }
11740
0
    } else {
11741
0
      NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11742
0
      NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11743
0
      ErrorFound = NotABinaryExpression;
11744
0
    }
11745
0
  } else {
11746
0
    ErrorLoc = AtomicBinOp->getExprLoc();
11747
0
    ErrorRange = AtomicBinOp->getSourceRange();
11748
0
    NoteLoc = AtomicBinOp->getOperatorLoc();
11749
0
    NoteRange = SourceRange(NoteLoc, NoteLoc);
11750
0
    ErrorFound = NotAnAssignmentOp;
11751
0
  }
11752
0
  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11753
0
    SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11754
0
    SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11755
0
    return true;
11756
0
  }
11757
0
  if (SemaRef.CurContext->isDependentContext())
11758
0
    E = X = UpdateExpr = nullptr;
11759
0
  return ErrorFound != NoError;
11760
0
}
11761
11762
bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11763
0
                                               unsigned NoteId) {
11764
0
  ExprAnalysisErrorCode ErrorFound = NoError;
11765
0
  SourceLocation ErrorLoc, NoteLoc;
11766
0
  SourceRange ErrorRange, NoteRange;
11767
  // Allowed constructs are:
11768
  //  x++;
11769
  //  x--;
11770
  //  ++x;
11771
  //  --x;
11772
  //  x binop= expr;
11773
  //  x = x binop expr;
11774
  //  x = expr binop x;
11775
0
  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11776
0
    AtomicBody = AtomicBody->IgnoreParenImpCasts();
11777
0
    if (AtomicBody->getType()->isScalarType() ||
11778
0
        AtomicBody->isInstantiationDependent()) {
11779
0
      if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11780
0
              AtomicBody->IgnoreParenImpCasts())) {
11781
        // Check for Compound Assignment Operation
11782
0
        Op = BinaryOperator::getOpForCompoundAssignment(
11783
0
            AtomicCompAssignOp->getOpcode());
11784
0
        OpLoc = AtomicCompAssignOp->getOperatorLoc();
11785
0
        E = AtomicCompAssignOp->getRHS();
11786
0
        X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11787
0
        IsXLHSInRHSPart = true;
11788
0
      } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11789
0
                     AtomicBody->IgnoreParenImpCasts())) {
11790
        // Check for Binary Operation
11791
0
        if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11792
0
          return true;
11793
0
      } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11794
0
                     AtomicBody->IgnoreParenImpCasts())) {
11795
        // Check for Unary Operation
11796
0
        if (AtomicUnaryOp->isIncrementDecrementOp()) {
11797
0
          IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11798
0
          Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11799
0
          OpLoc = AtomicUnaryOp->getOperatorLoc();
11800
0
          X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11801
0
          E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11802
0
          IsXLHSInRHSPart = true;
11803
0
        } else {
11804
0
          ErrorFound = NotAnUnaryIncDecExpression;
11805
0
          ErrorLoc = AtomicUnaryOp->getExprLoc();
11806
0
          ErrorRange = AtomicUnaryOp->getSourceRange();
11807
0
          NoteLoc = AtomicUnaryOp->getOperatorLoc();
11808
0
          NoteRange = SourceRange(NoteLoc, NoteLoc);
11809
0
        }
11810
0
      } else if (!AtomicBody->isInstantiationDependent()) {
11811
0
        ErrorFound = NotABinaryOrUnaryExpression;
11812
0
        NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11813
0
        NoteRange = ErrorRange = AtomicBody->getSourceRange();
11814
0
      } else if (AtomicBody->containsErrors()) {
11815
0
        ErrorFound = NotAValidExpression;
11816
0
        NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11817
0
        NoteRange = ErrorRange = AtomicBody->getSourceRange();
11818
0
      }
11819
0
    } else {
11820
0
      ErrorFound = NotAScalarType;
11821
0
      NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11822
0
      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11823
0
    }
11824
0
  } else {
11825
0
    ErrorFound = NotAnExpression;
11826
0
    NoteLoc = ErrorLoc = S->getBeginLoc();
11827
0
    NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11828
0
  }
11829
0
  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11830
0
    SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11831
0
    SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11832
0
    return true;
11833
0
  }
11834
0
  if (SemaRef.CurContext->isDependentContext())
11835
0
    E = X = UpdateExpr = nullptr;
11836
0
  if (ErrorFound == NoError && E && X) {
11837
    // Build an update expression of form 'OpaqueValueExpr(x) binop
11838
    // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11839
    // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11840
0
    auto *OVEX = new (SemaRef.getASTContext())
11841
0
        OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11842
0
    auto *OVEExpr = new (SemaRef.getASTContext())
11843
0
        OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
11844
0
    ExprResult Update =
11845
0
        SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11846
0
                                   IsXLHSInRHSPart ? OVEExpr : OVEX);
11847
0
    if (Update.isInvalid())
11848
0
      return true;
11849
0
    Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11850
0
                                               Sema::AA_Casting);
11851
0
    if (Update.isInvalid())
11852
0
      return true;
11853
0
    UpdateExpr = Update.get();
11854
0
  }
11855
0
  return ErrorFound != NoError;
11856
0
}
11857
11858
/// Get the node id of the fixed point of an expression \a S.
11859
0
llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11860
0
  llvm::FoldingSetNodeID Id;
11861
0
  S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11862
0
  return Id;
11863
0
}
11864
11865
/// Check if two expressions are same.
11866
bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11867
0
                            const Expr *RHS) {
11868
0
  return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11869
0
}
11870
11871
class OpenMPAtomicCompareChecker {
11872
public:
11873
  /// All kinds of errors that can occur in `atomic compare`
11874
  enum ErrorTy {
11875
    /// Empty compound statement.
11876
    NoStmt = 0,
11877
    /// More than one statement in a compound statement.
11878
    MoreThanOneStmt,
11879
    /// Not an assignment binary operator.
11880
    NotAnAssignment,
11881
    /// Not a conditional operator.
11882
    NotCondOp,
11883
    /// Wrong false expr. According to the spec, 'x' should be at the false
11884
    /// expression of a conditional expression.
11885
    WrongFalseExpr,
11886
    /// The condition of a conditional expression is not a binary operator.
11887
    NotABinaryOp,
11888
    /// Invalid binary operator (not <, >, or ==).
11889
    InvalidBinaryOp,
11890
    /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11891
    InvalidComparison,
11892
    /// X is not a lvalue.
11893
    XNotLValue,
11894
    /// Not a scalar.
11895
    NotScalar,
11896
    /// Not an integer.
11897
    NotInteger,
11898
    /// 'else' statement is not expected.
11899
    UnexpectedElse,
11900
    /// Not an equality operator.
11901
    NotEQ,
11902
    /// Invalid assignment (not v == x).
11903
    InvalidAssignment,
11904
    /// Not if statement
11905
    NotIfStmt,
11906
    /// More than two statements in a compund statement.
11907
    MoreThanTwoStmts,
11908
    /// Not a compound statement.
11909
    NotCompoundStmt,
11910
    /// No else statement.
11911
    NoElse,
11912
    /// Not 'if (r)'.
11913
    InvalidCondition,
11914
    /// No error.
11915
    NoError,
11916
  };
11917
11918
  struct ErrorInfoTy {
11919
    ErrorTy Error;
11920
    SourceLocation ErrorLoc;
11921
    SourceRange ErrorRange;
11922
    SourceLocation NoteLoc;
11923
    SourceRange NoteRange;
11924
  };
11925
11926
0
  OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11927
11928
  /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11929
  bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11930
11931
0
  Expr *getX() const { return X; }
11932
0
  Expr *getE() const { return E; }
11933
0
  Expr *getD() const { return D; }
11934
0
  Expr *getCond() const { return C; }
11935
0
  bool isXBinopExpr() const { return IsXBinopExpr; }
11936
11937
protected:
11938
  /// Reference to ASTContext
11939
  ASTContext &ContextRef;
11940
  /// 'x' lvalue part of the source atomic expression.
11941
  Expr *X = nullptr;
11942
  /// 'expr' or 'e' rvalue part of the source atomic expression.
11943
  Expr *E = nullptr;
11944
  /// 'd' rvalue part of the source atomic expression.
11945
  Expr *D = nullptr;
11946
  /// 'cond' part of the source atomic expression. It is in one of the following
11947
  /// forms:
11948
  /// expr ordop x
11949
  /// x ordop expr
11950
  /// x == e
11951
  /// e == x
11952
  Expr *C = nullptr;
11953
  /// True if the cond expr is in the form of 'x ordop expr'.
11954
  bool IsXBinopExpr = true;
11955
11956
  /// Check if it is a valid conditional update statement (cond-update-stmt).
11957
  bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11958
11959
  /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11960
  bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11961
11962
  /// Check if all captured values have right type.
11963
  bool checkType(ErrorInfoTy &ErrorInfo) const;
11964
11965
  static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11966
0
                         bool ShouldBeLValue, bool ShouldBeInteger = false) {
11967
0
    if (E->isInstantiationDependent())
11968
0
      return true;
11969
11970
0
    if (ShouldBeLValue && !E->isLValue()) {
11971
0
      ErrorInfo.Error = ErrorTy::XNotLValue;
11972
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11973
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11974
0
      return false;
11975
0
    }
11976
11977
0
    QualType QTy = E->getType();
11978
0
    if (!QTy->isScalarType()) {
11979
0
      ErrorInfo.Error = ErrorTy::NotScalar;
11980
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11981
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11982
0
      return false;
11983
0
    }
11984
0
    if (ShouldBeInteger && !QTy->isIntegerType()) {
11985
0
      ErrorInfo.Error = ErrorTy::NotInteger;
11986
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11987
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11988
0
      return false;
11989
0
    }
11990
11991
0
    return true;
11992
0
  }
11993
  };
11994
11995
bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11996
0
                                                     ErrorInfoTy &ErrorInfo) {
11997
0
  auto *Then = S->getThen();
11998
0
  if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11999
0
    if (CS->body_empty()) {
12000
0
      ErrorInfo.Error = ErrorTy::NoStmt;
12001
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12002
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12003
0
      return false;
12004
0
    }
12005
0
    if (CS->size() > 1) {
12006
0
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12007
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12008
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12009
0
      return false;
12010
0
    }
12011
0
    Then = CS->body_front();
12012
0
  }
12013
12014
0
  auto *BO = dyn_cast<BinaryOperator>(Then);
12015
0
  if (!BO) {
12016
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12017
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12018
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12019
0
    return false;
12020
0
  }
12021
0
  if (BO->getOpcode() != BO_Assign) {
12022
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12023
0
    ErrorInfo.ErrorLoc = BO->getExprLoc();
12024
0
    ErrorInfo.NoteLoc = BO->getOperatorLoc();
12025
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12026
0
    return false;
12027
0
  }
12028
12029
0
  X = BO->getLHS();
12030
12031
0
  auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12032
0
  if (!Cond) {
12033
0
    ErrorInfo.Error = ErrorTy::NotABinaryOp;
12034
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12035
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12036
0
    return false;
12037
0
  }
12038
12039
0
  switch (Cond->getOpcode()) {
12040
0
  case BO_EQ: {
12041
0
    C = Cond;
12042
0
    D = BO->getRHS();
12043
0
    if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12044
0
      E = Cond->getRHS();
12045
0
    } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12046
0
      E = Cond->getLHS();
12047
0
    } else {
12048
0
      ErrorInfo.Error = ErrorTy::InvalidComparison;
12049
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12050
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12051
0
      return false;
12052
0
    }
12053
0
    break;
12054
0
  }
12055
0
  case BO_LT:
12056
0
  case BO_GT: {
12057
0
    E = BO->getRHS();
12058
0
    if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
12059
0
        checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12060
0
      C = Cond;
12061
0
    } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12062
0
               checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12063
0
      C = Cond;
12064
0
      IsXBinopExpr = false;
12065
0
    } else {
12066
0
      ErrorInfo.Error = ErrorTy::InvalidComparison;
12067
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12068
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12069
0
      return false;
12070
0
    }
12071
0
    break;
12072
0
  }
12073
0
  default:
12074
0
    ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12075
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12076
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12077
0
    return false;
12078
0
  }
12079
12080
0
  if (S->getElse()) {
12081
0
    ErrorInfo.Error = ErrorTy::UnexpectedElse;
12082
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
12083
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
12084
0
    return false;
12085
0
  }
12086
12087
0
  return true;
12088
0
}
12089
12090
bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
12091
0
                                                   ErrorInfoTy &ErrorInfo) {
12092
0
  auto *BO = dyn_cast<BinaryOperator>(S);
12093
0
  if (!BO) {
12094
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12095
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12096
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12097
0
    return false;
12098
0
  }
12099
0
  if (BO->getOpcode() != BO_Assign) {
12100
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12101
0
    ErrorInfo.ErrorLoc = BO->getExprLoc();
12102
0
    ErrorInfo.NoteLoc = BO->getOperatorLoc();
12103
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12104
0
    return false;
12105
0
  }
12106
12107
0
  X = BO->getLHS();
12108
12109
0
  auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
12110
0
  if (!CO) {
12111
0
    ErrorInfo.Error = ErrorTy::NotCondOp;
12112
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
12113
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
12114
0
    return false;
12115
0
  }
12116
12117
0
  if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
12118
0
    ErrorInfo.Error = ErrorTy::WrongFalseExpr;
12119
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
12120
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12121
0
        CO->getFalseExpr()->getSourceRange();
12122
0
    return false;
12123
0
  }
12124
12125
0
  auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
12126
0
  if (!Cond) {
12127
0
    ErrorInfo.Error = ErrorTy::NotABinaryOp;
12128
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
12129
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12130
0
        CO->getCond()->getSourceRange();
12131
0
    return false;
12132
0
  }
12133
12134
0
  switch (Cond->getOpcode()) {
12135
0
  case BO_EQ: {
12136
0
    C = Cond;
12137
0
    D = CO->getTrueExpr();
12138
0
    if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12139
0
      E = Cond->getRHS();
12140
0
    } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12141
0
      E = Cond->getLHS();
12142
0
    } else {
12143
0
      ErrorInfo.Error = ErrorTy::InvalidComparison;
12144
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12145
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12146
0
      return false;
12147
0
    }
12148
0
    break;
12149
0
  }
12150
0
  case BO_LT:
12151
0
  case BO_GT: {
12152
0
    E = CO->getTrueExpr();
12153
0
    if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
12154
0
        checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12155
0
      C = Cond;
12156
0
    } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12157
0
               checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12158
0
      C = Cond;
12159
0
      IsXBinopExpr = false;
12160
0
    } else {
12161
0
      ErrorInfo.Error = ErrorTy::InvalidComparison;
12162
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12163
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12164
0
      return false;
12165
0
    }
12166
0
    break;
12167
0
  }
12168
0
  default:
12169
0
    ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12170
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12171
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12172
0
    return false;
12173
0
  }
12174
12175
0
  return true;
12176
0
}
12177
12178
0
bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
12179
  // 'x' and 'e' cannot be nullptr
12180
0
  assert(X && E && "X and E cannot be nullptr");
12181
12182
0
  if (!CheckValue(X, ErrorInfo, true))
12183
0
    return false;
12184
12185
0
  if (!CheckValue(E, ErrorInfo, false))
12186
0
    return false;
12187
12188
0
  if (D && !CheckValue(D, ErrorInfo, false))
12189
0
    return false;
12190
12191
0
  return true;
12192
0
}
12193
12194
bool OpenMPAtomicCompareChecker::checkStmt(
12195
0
    Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
12196
0
  auto *CS = dyn_cast<CompoundStmt>(S);
12197
0
  if (CS) {
12198
0
    if (CS->body_empty()) {
12199
0
      ErrorInfo.Error = ErrorTy::NoStmt;
12200
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12201
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12202
0
      return false;
12203
0
    }
12204
12205
0
    if (CS->size() != 1) {
12206
0
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12207
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12208
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12209
0
      return false;
12210
0
    }
12211
0
    S = CS->body_front();
12212
0
  }
12213
12214
0
  auto Res = false;
12215
12216
0
  if (auto *IS = dyn_cast<IfStmt>(S)) {
12217
    // Check if the statement is in one of the following forms
12218
    // (cond-update-stmt):
12219
    // if (expr ordop x) { x = expr; }
12220
    // if (x ordop expr) { x = expr; }
12221
    // if (x == e) { x = d; }
12222
0
    Res = checkCondUpdateStmt(IS, ErrorInfo);
12223
0
  } else {
12224
    // Check if the statement is in one of the following forms (cond-expr-stmt):
12225
    // x = expr ordop x ? expr : x;
12226
    // x = x ordop expr ? expr : x;
12227
    // x = x == e ? d : x;
12228
0
    Res = checkCondExprStmt(S, ErrorInfo);
12229
0
  }
12230
12231
0
  if (!Res)
12232
0
    return false;
12233
12234
0
  return checkType(ErrorInfo);
12235
0
}
12236
12237
class OpenMPAtomicCompareCaptureChecker final
12238
    : public OpenMPAtomicCompareChecker {
12239
public:
12240
0
  OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
12241
12242
0
  Expr *getV() const { return V; }
12243
0
  Expr *getR() const { return R; }
12244
0
  bool isFailOnly() const { return IsFailOnly; }
12245
0
  bool isPostfixUpdate() const { return IsPostfixUpdate; }
12246
12247
  /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
12248
  bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
12249
12250
private:
12251
  bool checkType(ErrorInfoTy &ErrorInfo);
12252
12253
  // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
12254
  // form of 'conditional-update-capture-atomic' structured block on the v5.2
12255
  // spec p.p. 82:
12256
  // (1) { v = x; cond-update-stmt }
12257
  // (2) { cond-update-stmt v = x; }
12258
  // (3) if(x == e) { x = d; } else { v = x; }
12259
  // (4) { r = x == e; if(r) { x = d; } }
12260
  // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
12261
12262
  /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
12263
  bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
12264
12265
  /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
12266
  /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
12267
  bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
12268
12269
  /// 'v' lvalue part of the source atomic expression.
12270
  Expr *V = nullptr;
12271
  /// 'r' lvalue part of the source atomic expression.
12272
  Expr *R = nullptr;
12273
  /// If 'v' is only updated when the comparison fails.
12274
  bool IsFailOnly = false;
12275
  /// If original value of 'x' must be stored in 'v', not an updated one.
12276
  bool IsPostfixUpdate = false;
12277
};
12278
12279
0
bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
12280
0
  if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
12281
0
    return false;
12282
12283
0
  if (V && !CheckValue(V, ErrorInfo, true))
12284
0
    return false;
12285
12286
0
  if (R && !CheckValue(R, ErrorInfo, true, true))
12287
0
    return false;
12288
12289
0
  return true;
12290
0
}
12291
12292
bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
12293
0
                                                   ErrorInfoTy &ErrorInfo) {
12294
0
  IsFailOnly = true;
12295
12296
0
  auto *Then = S->getThen();
12297
0
  if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
12298
0
    if (CS->body_empty()) {
12299
0
      ErrorInfo.Error = ErrorTy::NoStmt;
12300
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12301
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12302
0
      return false;
12303
0
    }
12304
0
    if (CS->size() > 1) {
12305
0
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12306
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12307
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12308
0
      return false;
12309
0
    }
12310
0
    Then = CS->body_front();
12311
0
  }
12312
12313
0
  auto *BO = dyn_cast<BinaryOperator>(Then);
12314
0
  if (!BO) {
12315
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12316
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12317
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12318
0
    return false;
12319
0
  }
12320
0
  if (BO->getOpcode() != BO_Assign) {
12321
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12322
0
    ErrorInfo.ErrorLoc = BO->getExprLoc();
12323
0
    ErrorInfo.NoteLoc = BO->getOperatorLoc();
12324
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12325
0
    return false;
12326
0
  }
12327
12328
0
  X = BO->getLHS();
12329
0
  D = BO->getRHS();
12330
12331
0
  auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12332
0
  if (!Cond) {
12333
0
    ErrorInfo.Error = ErrorTy::NotABinaryOp;
12334
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12335
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12336
0
    return false;
12337
0
  }
12338
0
  if (Cond->getOpcode() != BO_EQ) {
12339
0
    ErrorInfo.Error = ErrorTy::NotEQ;
12340
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12341
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12342
0
    return false;
12343
0
  }
12344
12345
0
  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12346
0
    E = Cond->getRHS();
12347
0
  } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12348
0
    E = Cond->getLHS();
12349
0
  } else {
12350
0
    ErrorInfo.Error = ErrorTy::InvalidComparison;
12351
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12352
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12353
0
    return false;
12354
0
  }
12355
12356
0
  C = Cond;
12357
12358
0
  if (!S->getElse()) {
12359
0
    ErrorInfo.Error = ErrorTy::NoElse;
12360
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12361
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12362
0
    return false;
12363
0
  }
12364
12365
0
  auto *Else = S->getElse();
12366
0
  if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
12367
0
    if (CS->body_empty()) {
12368
0
      ErrorInfo.Error = ErrorTy::NoStmt;
12369
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12370
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12371
0
      return false;
12372
0
    }
12373
0
    if (CS->size() > 1) {
12374
0
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12375
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12376
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12377
0
      return false;
12378
0
    }
12379
0
    Else = CS->body_front();
12380
0
  }
12381
12382
0
  auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12383
0
  if (!ElseBO) {
12384
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12385
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12386
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12387
0
    return false;
12388
0
  }
12389
0
  if (ElseBO->getOpcode() != BO_Assign) {
12390
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12391
0
    ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12392
0
    ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12393
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12394
0
    return false;
12395
0
  }
12396
12397
0
  if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12398
0
    ErrorInfo.Error = ErrorTy::InvalidAssignment;
12399
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12400
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12401
0
        ElseBO->getRHS()->getSourceRange();
12402
0
    return false;
12403
0
  }
12404
12405
0
  V = ElseBO->getLHS();
12406
12407
0
  return checkType(ErrorInfo);
12408
0
}
12409
12410
bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
12411
0
                                                    ErrorInfoTy &ErrorInfo) {
12412
  // We don't check here as they should be already done before call this
12413
  // function.
12414
0
  auto *CS = cast<CompoundStmt>(S);
12415
0
  assert(CS->size() == 2 && "CompoundStmt size is not expected");
12416
0
  auto *S1 = cast<BinaryOperator>(CS->body_front());
12417
0
  auto *S2 = cast<IfStmt>(CS->body_back());
12418
0
  assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
12419
12420
0
  if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12421
0
    ErrorInfo.Error = ErrorTy::InvalidCondition;
12422
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12423
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12424
0
    return false;
12425
0
  }
12426
12427
0
  R = S1->getLHS();
12428
12429
0
  auto *Then = S2->getThen();
12430
0
  if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12431
0
    if (ThenCS->body_empty()) {
12432
0
      ErrorInfo.Error = ErrorTy::NoStmt;
12433
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12434
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12435
0
      return false;
12436
0
    }
12437
0
    if (ThenCS->size() > 1) {
12438
0
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12439
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12440
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12441
0
      return false;
12442
0
    }
12443
0
    Then = ThenCS->body_front();
12444
0
  }
12445
12446
0
  auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12447
0
  if (!ThenBO) {
12448
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12449
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12450
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12451
0
    return false;
12452
0
  }
12453
0
  if (ThenBO->getOpcode() != BO_Assign) {
12454
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12455
0
    ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12456
0
    ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12457
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12458
0
    return false;
12459
0
  }
12460
12461
0
  X = ThenBO->getLHS();
12462
0
  D = ThenBO->getRHS();
12463
12464
0
  auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12465
0
  if (BO->getOpcode() != BO_EQ) {
12466
0
    ErrorInfo.Error = ErrorTy::NotEQ;
12467
0
    ErrorInfo.ErrorLoc = BO->getExprLoc();
12468
0
    ErrorInfo.NoteLoc = BO->getOperatorLoc();
12469
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12470
0
    return false;
12471
0
  }
12472
12473
0
  C = BO;
12474
12475
0
  if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
12476
0
    E = BO->getRHS();
12477
0
  } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
12478
0
    E = BO->getLHS();
12479
0
  } else {
12480
0
    ErrorInfo.Error = ErrorTy::InvalidComparison;
12481
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12482
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12483
0
    return false;
12484
0
  }
12485
12486
0
  if (S2->getElse()) {
12487
0
    IsFailOnly = true;
12488
12489
0
    auto *Else = S2->getElse();
12490
0
    if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12491
0
      if (ElseCS->body_empty()) {
12492
0
        ErrorInfo.Error = ErrorTy::NoStmt;
12493
0
        ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12494
0
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12495
0
        return false;
12496
0
      }
12497
0
      if (ElseCS->size() > 1) {
12498
0
        ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12499
0
        ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12500
0
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12501
0
        return false;
12502
0
      }
12503
0
      Else = ElseCS->body_front();
12504
0
    }
12505
12506
0
    auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12507
0
    if (!ElseBO) {
12508
0
      ErrorInfo.Error = ErrorTy::NotAnAssignment;
12509
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12510
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12511
0
      return false;
12512
0
    }
12513
0
    if (ElseBO->getOpcode() != BO_Assign) {
12514
0
      ErrorInfo.Error = ErrorTy::NotAnAssignment;
12515
0
      ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12516
0
      ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12517
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12518
0
      return false;
12519
0
    }
12520
0
    if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12521
0
      ErrorInfo.Error = ErrorTy::InvalidAssignment;
12522
0
      ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12523
0
      ErrorInfo.NoteLoc = X->getExprLoc();
12524
0
      ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12525
0
      ErrorInfo.NoteRange = X->getSourceRange();
12526
0
      return false;
12527
0
    }
12528
12529
0
    V = ElseBO->getLHS();
12530
0
  }
12531
12532
0
  return checkType(ErrorInfo);
12533
0
}
12534
12535
bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
12536
0
                                                  ErrorInfoTy &ErrorInfo) {
12537
  // if(x == e) { x = d; } else { v = x; }
12538
0
  if (auto *IS = dyn_cast<IfStmt>(S))
12539
0
    return checkForm3(IS, ErrorInfo);
12540
12541
0
  auto *CS = dyn_cast<CompoundStmt>(S);
12542
0
  if (!CS) {
12543
0
    ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12544
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12545
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12546
0
    return false;
12547
0
  }
12548
0
  if (CS->body_empty()) {
12549
0
    ErrorInfo.Error = ErrorTy::NoStmt;
12550
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12551
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12552
0
    return false;
12553
0
  }
12554
12555
  // { if(x == e) { x = d; } else { v = x; } }
12556
0
  if (CS->size() == 1) {
12557
0
    auto *IS = dyn_cast<IfStmt>(CS->body_front());
12558
0
    if (!IS) {
12559
0
      ErrorInfo.Error = ErrorTy::NotIfStmt;
12560
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
12561
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12562
0
          CS->body_front()->getSourceRange();
12563
0
      return false;
12564
0
    }
12565
12566
0
    return checkForm3(IS, ErrorInfo);
12567
0
  } else if (CS->size() == 2) {
12568
0
    auto *S1 = CS->body_front();
12569
0
    auto *S2 = CS->body_back();
12570
12571
0
    Stmt *UpdateStmt = nullptr;
12572
0
    Stmt *CondUpdateStmt = nullptr;
12573
0
    Stmt *CondExprStmt = nullptr;
12574
12575
0
    if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
12576
      // It could be one of the following cases:
12577
      // { v = x; cond-update-stmt }
12578
      // { v = x; cond-expr-stmt }
12579
      // { cond-expr-stmt; v = x; }
12580
      // form 45
12581
0
      if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12582
0
          isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12583
        // check if form 45
12584
0
        if (isa<IfStmt>(S2))
12585
0
          return checkForm45(CS, ErrorInfo);
12586
        // { cond-expr-stmt; v = x; }
12587
0
        CondExprStmt = S1;
12588
0
        UpdateStmt = S2;
12589
0
      } else {
12590
0
        IsPostfixUpdate = true;
12591
0
        UpdateStmt = S1;
12592
0
        if (isa<IfStmt>(S2)) {
12593
          // { v = x; cond-update-stmt }
12594
0
          CondUpdateStmt = S2;
12595
0
        } else {
12596
          // { v = x; cond-expr-stmt }
12597
0
          CondExprStmt = S2;
12598
0
        }
12599
0
      }
12600
0
    } else {
12601
      // { cond-update-stmt v = x; }
12602
0
      UpdateStmt = S2;
12603
0
      CondUpdateStmt = S1;
12604
0
    }
12605
12606
0
    auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
12607
0
      auto *IS = dyn_cast<IfStmt>(CUS);
12608
0
      if (!IS) {
12609
0
        ErrorInfo.Error = ErrorTy::NotIfStmt;
12610
0
        ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12611
0
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12612
0
        return false;
12613
0
      }
12614
12615
0
      return checkCondUpdateStmt(IS, ErrorInfo);
12616
0
    };
12617
12618
    // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12619
0
    auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
12620
0
      auto *BO = dyn_cast<BinaryOperator>(US);
12621
0
      if (!BO) {
12622
0
        ErrorInfo.Error = ErrorTy::NotAnAssignment;
12623
0
        ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12624
0
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12625
0
        return false;
12626
0
      }
12627
0
      if (BO->getOpcode() != BO_Assign) {
12628
0
        ErrorInfo.Error = ErrorTy::NotAnAssignment;
12629
0
        ErrorInfo.ErrorLoc = BO->getExprLoc();
12630
0
        ErrorInfo.NoteLoc = BO->getOperatorLoc();
12631
0
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12632
0
        return false;
12633
0
      }
12634
0
      if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12635
0
        ErrorInfo.Error = ErrorTy::InvalidAssignment;
12636
0
        ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12637
0
        ErrorInfo.NoteLoc = this->X->getExprLoc();
12638
0
        ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12639
0
        ErrorInfo.NoteRange = this->X->getSourceRange();
12640
0
        return false;
12641
0
      }
12642
12643
0
      this->V = BO->getLHS();
12644
12645
0
      return true;
12646
0
    };
12647
12648
0
    if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12649
0
      return false;
12650
0
    if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12651
0
      return false;
12652
0
    if (!CheckUpdateStmt(UpdateStmt))
12653
0
      return false;
12654
0
  } else {
12655
0
    ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12656
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12657
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12658
0
    return false;
12659
0
  }
12660
12661
0
  return checkType(ErrorInfo);
12662
0
}
12663
} // namespace
12664
12665
StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
12666
                                            Stmt *AStmt,
12667
                                            SourceLocation StartLoc,
12668
0
                                            SourceLocation EndLoc) {
12669
  // Register location of the first atomic directive.
12670
0
  DSAStack->addAtomicDirectiveLoc(StartLoc);
12671
0
  if (!AStmt)
12672
0
    return StmtError();
12673
12674
  // 1.2.2 OpenMP Language Terminology
12675
  // Structured block - An executable statement with a single entry at the
12676
  // top and a single exit at the bottom.
12677
  // The point of exit cannot be a branch out of the structured block.
12678
  // longjmp() and throw() must not violate the entry/exit criteria.
12679
0
  OpenMPClauseKind AtomicKind = OMPC_unknown;
12680
0
  SourceLocation AtomicKindLoc;
12681
0
  OpenMPClauseKind MemOrderKind = OMPC_unknown;
12682
0
  SourceLocation MemOrderLoc;
12683
0
  bool MutexClauseEncountered = false;
12684
0
  llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12685
0
  for (const OMPClause *C : Clauses) {
12686
0
    switch (C->getClauseKind()) {
12687
0
    case OMPC_read:
12688
0
    case OMPC_write:
12689
0
    case OMPC_update:
12690
0
      MutexClauseEncountered = true;
12691
0
      [[fallthrough]];
12692
0
    case OMPC_capture:
12693
0
    case OMPC_compare: {
12694
0
      if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12695
0
        Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12696
0
            << SourceRange(C->getBeginLoc(), C->getEndLoc());
12697
0
        Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12698
0
            << getOpenMPClauseName(AtomicKind);
12699
0
      } else {
12700
0
        AtomicKind = C->getClauseKind();
12701
0
        AtomicKindLoc = C->getBeginLoc();
12702
0
        if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12703
0
          Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12704
0
              << SourceRange(C->getBeginLoc(), C->getEndLoc());
12705
0
          Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12706
0
              << getOpenMPClauseName(AtomicKind);
12707
0
        }
12708
0
      }
12709
0
      break;
12710
0
    }
12711
0
    case OMPC_fail: {
12712
0
      if (!EncounteredAtomicKinds.contains(OMPC_compare)) {
12713
0
        Diag(C->getBeginLoc(), diag::err_omp_atomic_fail_no_compare)
12714
0
            << SourceRange(C->getBeginLoc(), C->getEndLoc());
12715
0
        return StmtError();
12716
0
      }
12717
0
      break;
12718
0
    }
12719
0
    case OMPC_seq_cst:
12720
0
    case OMPC_acq_rel:
12721
0
    case OMPC_acquire:
12722
0
    case OMPC_release:
12723
0
    case OMPC_relaxed: {
12724
0
      if (MemOrderKind != OMPC_unknown) {
12725
0
        Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12726
0
            << getOpenMPDirectiveName(OMPD_atomic) << 0
12727
0
            << SourceRange(C->getBeginLoc(), C->getEndLoc());
12728
0
        Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12729
0
            << getOpenMPClauseName(MemOrderKind);
12730
0
      } else {
12731
0
        MemOrderKind = C->getClauseKind();
12732
0
        MemOrderLoc = C->getBeginLoc();
12733
0
      }
12734
0
      break;
12735
0
    }
12736
    // The following clauses are allowed, but we don't need to do anything here.
12737
0
    case OMPC_hint:
12738
0
      break;
12739
0
    default:
12740
0
      llvm_unreachable("unknown clause is encountered");
12741
0
    }
12742
0
  }
12743
0
  bool IsCompareCapture = false;
12744
0
  if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12745
0
      EncounteredAtomicKinds.contains(OMPC_capture)) {
12746
0
    IsCompareCapture = true;
12747
0
    AtomicKind = OMPC_compare;
12748
0
  }
12749
  // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12750
  // If atomic-clause is read then memory-order-clause must not be acq_rel or
12751
  // release.
12752
  // If atomic-clause is write then memory-order-clause must not be acq_rel or
12753
  // acquire.
12754
  // If atomic-clause is update or not present then memory-order-clause must not
12755
  // be acq_rel or acquire.
12756
0
  if ((AtomicKind == OMPC_read &&
12757
0
       (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12758
0
      ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12759
0
        AtomicKind == OMPC_unknown) &&
12760
0
       (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12761
0
    SourceLocation Loc = AtomicKindLoc;
12762
0
    if (AtomicKind == OMPC_unknown)
12763
0
      Loc = StartLoc;
12764
0
    Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12765
0
        << getOpenMPClauseName(AtomicKind)
12766
0
        << (AtomicKind == OMPC_unknown ? 1 : 0)
12767
0
        << getOpenMPClauseName(MemOrderKind);
12768
0
    Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12769
0
        << getOpenMPClauseName(MemOrderKind);
12770
0
  }
12771
12772
0
  Stmt *Body = AStmt;
12773
0
  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12774
0
    Body = EWC->getSubExpr();
12775
12776
0
  Expr *X = nullptr;
12777
0
  Expr *V = nullptr;
12778
0
  Expr *E = nullptr;
12779
0
  Expr *UE = nullptr;
12780
0
  Expr *D = nullptr;
12781
0
  Expr *CE = nullptr;
12782
0
  Expr *R = nullptr;
12783
0
  bool IsXLHSInRHSPart = false;
12784
0
  bool IsPostfixUpdate = false;
12785
0
  bool IsFailOnly = false;
12786
  // OpenMP [2.12.6, atomic Construct]
12787
  // In the next expressions:
12788
  // * x and v (as applicable) are both l-value expressions with scalar type.
12789
  // * During the execution of an atomic region, multiple syntactic
12790
  // occurrences of x must designate the same storage location.
12791
  // * Neither of v and expr (as applicable) may access the storage location
12792
  // designated by x.
12793
  // * Neither of x and expr (as applicable) may access the storage location
12794
  // designated by v.
12795
  // * expr is an expression with scalar type.
12796
  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12797
  // * binop, binop=, ++, and -- are not overloaded operators.
12798
  // * The expression x binop expr must be numerically equivalent to x binop
12799
  // (expr). This requirement is satisfied if the operators in expr have
12800
  // precedence greater than binop, or by using parentheses around expr or
12801
  // subexpressions of expr.
12802
  // * The expression expr binop x must be numerically equivalent to (expr)
12803
  // binop x. This requirement is satisfied if the operators in expr have
12804
  // precedence equal to or greater than binop, or by using parentheses around
12805
  // expr or subexpressions of expr.
12806
  // * For forms that allow multiple occurrences of x, the number of times
12807
  // that x is evaluated is unspecified.
12808
0
  if (AtomicKind == OMPC_read) {
12809
0
    enum {
12810
0
      NotAnExpression,
12811
0
      NotAnAssignmentOp,
12812
0
      NotAScalarType,
12813
0
      NotAnLValue,
12814
0
      NoError
12815
0
    } ErrorFound = NoError;
12816
0
    SourceLocation ErrorLoc, NoteLoc;
12817
0
    SourceRange ErrorRange, NoteRange;
12818
    // If clause is read:
12819
    //  v = x;
12820
0
    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12821
0
      const auto *AtomicBinOp =
12822
0
          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12823
0
      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12824
0
        X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12825
0
        V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12826
0
        if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12827
0
            (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12828
0
          if (!X->isLValue() || !V->isLValue()) {
12829
0
            const Expr *NotLValueExpr = X->isLValue() ? V : X;
12830
0
            ErrorFound = NotAnLValue;
12831
0
            ErrorLoc = AtomicBinOp->getExprLoc();
12832
0
            ErrorRange = AtomicBinOp->getSourceRange();
12833
0
            NoteLoc = NotLValueExpr->getExprLoc();
12834
0
            NoteRange = NotLValueExpr->getSourceRange();
12835
0
          }
12836
0
        } else if (!X->isInstantiationDependent() ||
12837
0
                   !V->isInstantiationDependent()) {
12838
0
          const Expr *NotScalarExpr =
12839
0
              (X->isInstantiationDependent() || X->getType()->isScalarType())
12840
0
                  ? V
12841
0
                  : X;
12842
0
          ErrorFound = NotAScalarType;
12843
0
          ErrorLoc = AtomicBinOp->getExprLoc();
12844
0
          ErrorRange = AtomicBinOp->getSourceRange();
12845
0
          NoteLoc = NotScalarExpr->getExprLoc();
12846
0
          NoteRange = NotScalarExpr->getSourceRange();
12847
0
        }
12848
0
      } else if (!AtomicBody->isInstantiationDependent()) {
12849
0
        ErrorFound = NotAnAssignmentOp;
12850
0
        ErrorLoc = AtomicBody->getExprLoc();
12851
0
        ErrorRange = AtomicBody->getSourceRange();
12852
0
        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12853
0
                              : AtomicBody->getExprLoc();
12854
0
        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12855
0
                                : AtomicBody->getSourceRange();
12856
0
      }
12857
0
    } else {
12858
0
      ErrorFound = NotAnExpression;
12859
0
      NoteLoc = ErrorLoc = Body->getBeginLoc();
12860
0
      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12861
0
    }
12862
0
    if (ErrorFound != NoError) {
12863
0
      Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12864
0
          << ErrorRange;
12865
0
      Diag(NoteLoc, diag::note_omp_atomic_read_write)
12866
0
          << ErrorFound << NoteRange;
12867
0
      return StmtError();
12868
0
    }
12869
0
    if (CurContext->isDependentContext())
12870
0
      V = X = nullptr;
12871
0
  } else if (AtomicKind == OMPC_write) {
12872
0
    enum {
12873
0
      NotAnExpression,
12874
0
      NotAnAssignmentOp,
12875
0
      NotAScalarType,
12876
0
      NotAnLValue,
12877
0
      NoError
12878
0
    } ErrorFound = NoError;
12879
0
    SourceLocation ErrorLoc, NoteLoc;
12880
0
    SourceRange ErrorRange, NoteRange;
12881
    // If clause is write:
12882
    //  x = expr;
12883
0
    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12884
0
      const auto *AtomicBinOp =
12885
0
          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12886
0
      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12887
0
        X = AtomicBinOp->getLHS();
12888
0
        E = AtomicBinOp->getRHS();
12889
0
        if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12890
0
            (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12891
0
          if (!X->isLValue()) {
12892
0
            ErrorFound = NotAnLValue;
12893
0
            ErrorLoc = AtomicBinOp->getExprLoc();
12894
0
            ErrorRange = AtomicBinOp->getSourceRange();
12895
0
            NoteLoc = X->getExprLoc();
12896
0
            NoteRange = X->getSourceRange();
12897
0
          }
12898
0
        } else if (!X->isInstantiationDependent() ||
12899
0
                   !E->isInstantiationDependent()) {
12900
0
          const Expr *NotScalarExpr =
12901
0
              (X->isInstantiationDependent() || X->getType()->isScalarType())
12902
0
                  ? E
12903
0
                  : X;
12904
0
          ErrorFound = NotAScalarType;
12905
0
          ErrorLoc = AtomicBinOp->getExprLoc();
12906
0
          ErrorRange = AtomicBinOp->getSourceRange();
12907
0
          NoteLoc = NotScalarExpr->getExprLoc();
12908
0
          NoteRange = NotScalarExpr->getSourceRange();
12909
0
        }
12910
0
      } else if (!AtomicBody->isInstantiationDependent()) {
12911
0
        ErrorFound = NotAnAssignmentOp;
12912
0
        ErrorLoc = AtomicBody->getExprLoc();
12913
0
        ErrorRange = AtomicBody->getSourceRange();
12914
0
        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12915
0
                              : AtomicBody->getExprLoc();
12916
0
        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12917
0
                                : AtomicBody->getSourceRange();
12918
0
      }
12919
0
    } else {
12920
0
      ErrorFound = NotAnExpression;
12921
0
      NoteLoc = ErrorLoc = Body->getBeginLoc();
12922
0
      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12923
0
    }
12924
0
    if (ErrorFound != NoError) {
12925
0
      Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12926
0
          << ErrorRange;
12927
0
      Diag(NoteLoc, diag::note_omp_atomic_read_write)
12928
0
          << ErrorFound << NoteRange;
12929
0
      return StmtError();
12930
0
    }
12931
0
    if (CurContext->isDependentContext())
12932
0
      E = X = nullptr;
12933
0
  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12934
    // If clause is update:
12935
    //  x++;
12936
    //  x--;
12937
    //  ++x;
12938
    //  --x;
12939
    //  x binop= expr;
12940
    //  x = x binop expr;
12941
    //  x = expr binop x;
12942
0
    OpenMPAtomicUpdateChecker Checker(*this);
12943
0
    if (Checker.checkStatement(
12944
0
            Body,
12945
0
            (AtomicKind == OMPC_update)
12946
0
                ? diag::err_omp_atomic_update_not_expression_statement
12947
0
                : diag::err_omp_atomic_not_expression_statement,
12948
0
            diag::note_omp_atomic_update))
12949
0
      return StmtError();
12950
0
    if (!CurContext->isDependentContext()) {
12951
0
      E = Checker.getExpr();
12952
0
      X = Checker.getX();
12953
0
      UE = Checker.getUpdateExpr();
12954
0
      IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12955
0
    }
12956
0
  } else if (AtomicKind == OMPC_capture) {
12957
0
    enum {
12958
0
      NotAnAssignmentOp,
12959
0
      NotACompoundStatement,
12960
0
      NotTwoSubstatements,
12961
0
      NotASpecificExpression,
12962
0
      NoError
12963
0
    } ErrorFound = NoError;
12964
0
    SourceLocation ErrorLoc, NoteLoc;
12965
0
    SourceRange ErrorRange, NoteRange;
12966
0
    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12967
      // If clause is a capture:
12968
      //  v = x++;
12969
      //  v = x--;
12970
      //  v = ++x;
12971
      //  v = --x;
12972
      //  v = x binop= expr;
12973
      //  v = x = x binop expr;
12974
      //  v = x = expr binop x;
12975
0
      const auto *AtomicBinOp =
12976
0
          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12977
0
      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12978
0
        V = AtomicBinOp->getLHS();
12979
0
        Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12980
0
        OpenMPAtomicUpdateChecker Checker(*this);
12981
0
        if (Checker.checkStatement(
12982
0
                Body, diag::err_omp_atomic_capture_not_expression_statement,
12983
0
                diag::note_omp_atomic_update))
12984
0
          return StmtError();
12985
0
        E = Checker.getExpr();
12986
0
        X = Checker.getX();
12987
0
        UE = Checker.getUpdateExpr();
12988
0
        IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12989
0
        IsPostfixUpdate = Checker.isPostfixUpdate();
12990
0
      } else if (!AtomicBody->isInstantiationDependent()) {
12991
0
        ErrorLoc = AtomicBody->getExprLoc();
12992
0
        ErrorRange = AtomicBody->getSourceRange();
12993
0
        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12994
0
                              : AtomicBody->getExprLoc();
12995
0
        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12996
0
                                : AtomicBody->getSourceRange();
12997
0
        ErrorFound = NotAnAssignmentOp;
12998
0
      }
12999
0
      if (ErrorFound != NoError) {
13000
0
        Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
13001
0
            << ErrorRange;
13002
0
        Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13003
0
        return StmtError();
13004
0
      }
13005
0
      if (CurContext->isDependentContext())
13006
0
        UE = V = E = X = nullptr;
13007
0
    } else {
13008
      // If clause is a capture:
13009
      //  { v = x; x = expr; }
13010
      //  { v = x; x++; }
13011
      //  { v = x; x--; }
13012
      //  { v = x; ++x; }
13013
      //  { v = x; --x; }
13014
      //  { v = x; x binop= expr; }
13015
      //  { v = x; x = x binop expr; }
13016
      //  { v = x; x = expr binop x; }
13017
      //  { x++; v = x; }
13018
      //  { x--; v = x; }
13019
      //  { ++x; v = x; }
13020
      //  { --x; v = x; }
13021
      //  { x binop= expr; v = x; }
13022
      //  { x = x binop expr; v = x; }
13023
      //  { x = expr binop x; v = x; }
13024
0
      if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
13025
        // Check that this is { expr1; expr2; }
13026
0
        if (CS->size() == 2) {
13027
0
          Stmt *First = CS->body_front();
13028
0
          Stmt *Second = CS->body_back();
13029
0
          if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
13030
0
            First = EWC->getSubExpr()->IgnoreParenImpCasts();
13031
0
          if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
13032
0
            Second = EWC->getSubExpr()->IgnoreParenImpCasts();
13033
          // Need to find what subexpression is 'v' and what is 'x'.
13034
0
          OpenMPAtomicUpdateChecker Checker(*this);
13035
0
          bool IsUpdateExprFound = !Checker.checkStatement(Second);
13036
0
          BinaryOperator *BinOp = nullptr;
13037
0
          if (IsUpdateExprFound) {
13038
0
            BinOp = dyn_cast<BinaryOperator>(First);
13039
0
            IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
13040
0
          }
13041
0
          if (IsUpdateExprFound && !CurContext->isDependentContext()) {
13042
            //  { v = x; x++; }
13043
            //  { v = x; x--; }
13044
            //  { v = x; ++x; }
13045
            //  { v = x; --x; }
13046
            //  { v = x; x binop= expr; }
13047
            //  { v = x; x = x binop expr; }
13048
            //  { v = x; x = expr binop x; }
13049
            // Check that the first expression has form v = x.
13050
0
            Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
13051
0
            llvm::FoldingSetNodeID XId, PossibleXId;
13052
0
            Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
13053
0
            PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
13054
0
            IsUpdateExprFound = XId == PossibleXId;
13055
0
            if (IsUpdateExprFound) {
13056
0
              V = BinOp->getLHS();
13057
0
              X = Checker.getX();
13058
0
              E = Checker.getExpr();
13059
0
              UE = Checker.getUpdateExpr();
13060
0
              IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13061
0
              IsPostfixUpdate = true;
13062
0
            }
13063
0
          }
13064
0
          if (!IsUpdateExprFound) {
13065
0
            IsUpdateExprFound = !Checker.checkStatement(First);
13066
0
            BinOp = nullptr;
13067
0
            if (IsUpdateExprFound) {
13068
0
              BinOp = dyn_cast<BinaryOperator>(Second);
13069
0
              IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
13070
0
            }
13071
0
            if (IsUpdateExprFound && !CurContext->isDependentContext()) {
13072
              //  { x++; v = x; }
13073
              //  { x--; v = x; }
13074
              //  { ++x; v = x; }
13075
              //  { --x; v = x; }
13076
              //  { x binop= expr; v = x; }
13077
              //  { x = x binop expr; v = x; }
13078
              //  { x = expr binop x; v = x; }
13079
              // Check that the second expression has form v = x.
13080
0
              Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
13081
0
              llvm::FoldingSetNodeID XId, PossibleXId;
13082
0
              Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
13083
0
              PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
13084
0
              IsUpdateExprFound = XId == PossibleXId;
13085
0
              if (IsUpdateExprFound) {
13086
0
                V = BinOp->getLHS();
13087
0
                X = Checker.getX();
13088
0
                E = Checker.getExpr();
13089
0
                UE = Checker.getUpdateExpr();
13090
0
                IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13091
0
                IsPostfixUpdate = false;
13092
0
              }
13093
0
            }
13094
0
          }
13095
0
          if (!IsUpdateExprFound) {
13096
            //  { v = x; x = expr; }
13097
0
            auto *FirstExpr = dyn_cast<Expr>(First);
13098
0
            auto *SecondExpr = dyn_cast<Expr>(Second);
13099
0
            if (!FirstExpr || !SecondExpr ||
13100
0
                !(FirstExpr->isInstantiationDependent() ||
13101
0
                  SecondExpr->isInstantiationDependent())) {
13102
0
              auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
13103
0
              if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
13104
0
                ErrorFound = NotAnAssignmentOp;
13105
0
                NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
13106
0
                                                : First->getBeginLoc();
13107
0
                NoteRange = ErrorRange = FirstBinOp
13108
0
                                             ? FirstBinOp->getSourceRange()
13109
0
                                             : SourceRange(ErrorLoc, ErrorLoc);
13110
0
              } else {
13111
0
                auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
13112
0
                if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
13113
0
                  ErrorFound = NotAnAssignmentOp;
13114
0
                  NoteLoc = ErrorLoc = SecondBinOp
13115
0
                                           ? SecondBinOp->getOperatorLoc()
13116
0
                                           : Second->getBeginLoc();
13117
0
                  NoteRange = ErrorRange =
13118
0
                      SecondBinOp ? SecondBinOp->getSourceRange()
13119
0
                                  : SourceRange(ErrorLoc, ErrorLoc);
13120
0
                } else {
13121
0
                  Expr *PossibleXRHSInFirst =
13122
0
                      FirstBinOp->getRHS()->IgnoreParenImpCasts();
13123
0
                  Expr *PossibleXLHSInSecond =
13124
0
                      SecondBinOp->getLHS()->IgnoreParenImpCasts();
13125
0
                  llvm::FoldingSetNodeID X1Id, X2Id;
13126
0
                  PossibleXRHSInFirst->Profile(X1Id, Context,
13127
0
                                               /*Canonical=*/true);
13128
0
                  PossibleXLHSInSecond->Profile(X2Id, Context,
13129
0
                                                /*Canonical=*/true);
13130
0
                  IsUpdateExprFound = X1Id == X2Id;
13131
0
                  if (IsUpdateExprFound) {
13132
0
                    V = FirstBinOp->getLHS();
13133
0
                    X = SecondBinOp->getLHS();
13134
0
                    E = SecondBinOp->getRHS();
13135
0
                    UE = nullptr;
13136
0
                    IsXLHSInRHSPart = false;
13137
0
                    IsPostfixUpdate = true;
13138
0
                  } else {
13139
0
                    ErrorFound = NotASpecificExpression;
13140
0
                    ErrorLoc = FirstBinOp->getExprLoc();
13141
0
                    ErrorRange = FirstBinOp->getSourceRange();
13142
0
                    NoteLoc = SecondBinOp->getLHS()->getExprLoc();
13143
0
                    NoteRange = SecondBinOp->getRHS()->getSourceRange();
13144
0
                  }
13145
0
                }
13146
0
              }
13147
0
            }
13148
0
          }
13149
0
        } else {
13150
0
          NoteLoc = ErrorLoc = Body->getBeginLoc();
13151
0
          NoteRange = ErrorRange =
13152
0
              SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
13153
0
          ErrorFound = NotTwoSubstatements;
13154
0
        }
13155
0
      } else {
13156
0
        NoteLoc = ErrorLoc = Body->getBeginLoc();
13157
0
        NoteRange = ErrorRange =
13158
0
            SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
13159
0
        ErrorFound = NotACompoundStatement;
13160
0
      }
13161
0
    }
13162
0
    if (ErrorFound != NoError) {
13163
0
      Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
13164
0
          << ErrorRange;
13165
0
      Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13166
0
      return StmtError();
13167
0
    }
13168
0
    if (CurContext->isDependentContext())
13169
0
      UE = V = E = X = nullptr;
13170
0
  } else if (AtomicKind == OMPC_compare) {
13171
0
    if (IsCompareCapture) {
13172
0
      OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
13173
0
      OpenMPAtomicCompareCaptureChecker Checker(*this);
13174
0
      if (!Checker.checkStmt(Body, ErrorInfo)) {
13175
0
        Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
13176
0
            << ErrorInfo.ErrorRange;
13177
0
        Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13178
0
            << ErrorInfo.Error << ErrorInfo.NoteRange;
13179
0
        return StmtError();
13180
0
      }
13181
0
      X = Checker.getX();
13182
0
      E = Checker.getE();
13183
0
      D = Checker.getD();
13184
0
      CE = Checker.getCond();
13185
0
      V = Checker.getV();
13186
0
      R = Checker.getR();
13187
      // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
13188
0
      IsXLHSInRHSPart = Checker.isXBinopExpr();
13189
0
      IsFailOnly = Checker.isFailOnly();
13190
0
      IsPostfixUpdate = Checker.isPostfixUpdate();
13191
0
    } else {
13192
0
      OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
13193
0
      OpenMPAtomicCompareChecker Checker(*this);
13194
0
      if (!Checker.checkStmt(Body, ErrorInfo)) {
13195
0
        Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
13196
0
            << ErrorInfo.ErrorRange;
13197
0
        Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13198
0
          << ErrorInfo.Error << ErrorInfo.NoteRange;
13199
0
        return StmtError();
13200
0
      }
13201
0
      X = Checker.getX();
13202
0
      E = Checker.getE();
13203
0
      D = Checker.getD();
13204
0
      CE = Checker.getCond();
13205
      // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
13206
0
      IsXLHSInRHSPart = Checker.isXBinopExpr();
13207
0
    }
13208
0
  }
13209
13210
0
  setFunctionHasBranchProtectedScope();
13211
13212
0
  return OMPAtomicDirective::Create(
13213
0
      Context, StartLoc, EndLoc, Clauses, AStmt,
13214
0
      {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
13215
0
}
13216
13217
StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
13218
                                            Stmt *AStmt,
13219
                                            SourceLocation StartLoc,
13220
0
                                            SourceLocation EndLoc) {
13221
0
  if (!AStmt)
13222
0
    return StmtError();
13223
13224
0
  auto *CS = cast<CapturedStmt>(AStmt);
13225
  // 1.2.2 OpenMP Language Terminology
13226
  // Structured block - An executable statement with a single entry at the
13227
  // top and a single exit at the bottom.
13228
  // The point of exit cannot be a branch out of the structured block.
13229
  // longjmp() and throw() must not violate the entry/exit criteria.
13230
0
  CS->getCapturedDecl()->setNothrow();
13231
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
13232
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
13233
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13234
    // 1.2.2 OpenMP Language Terminology
13235
    // Structured block - An executable statement with a single entry at the
13236
    // top and a single exit at the bottom.
13237
    // The point of exit cannot be a branch out of the structured block.
13238
    // longjmp() and throw() must not violate the entry/exit criteria.
13239
0
    CS->getCapturedDecl()->setNothrow();
13240
0
  }
13241
13242
  // OpenMP [2.16, Nesting of Regions]
13243
  // If specified, a teams construct must be contained within a target
13244
  // construct. That target construct must contain no statements or directives
13245
  // outside of the teams construct.
13246
0
  if (DSAStack->hasInnerTeamsRegion()) {
13247
0
    const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
13248
0
    bool OMPTeamsFound = true;
13249
0
    if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
13250
0
      auto I = CS->body_begin();
13251
0
      while (I != CS->body_end()) {
13252
0
        const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
13253
0
        if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
13254
0
            OMPTeamsFound) {
13255
13256
0
          OMPTeamsFound = false;
13257
0
          break;
13258
0
        }
13259
0
        ++I;
13260
0
      }
13261
0
      assert(I != CS->body_end() && "Not found statement");
13262
0
      S = *I;
13263
0
    } else {
13264
0
      const auto *OED = dyn_cast<OMPExecutableDirective>(S);
13265
0
      OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
13266
0
    }
13267
0
    if (!OMPTeamsFound) {
13268
0
      Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
13269
0
      Diag(DSAStack->getInnerTeamsRegionLoc(),
13270
0
           diag::note_omp_nested_teams_construct_here);
13271
0
      Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
13272
0
          << isa<OMPExecutableDirective>(S);
13273
0
      return StmtError();
13274
0
    }
13275
0
  }
13276
13277
0
  setFunctionHasBranchProtectedScope();
13278
13279
0
  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13280
0
}
13281
13282
StmtResult
13283
Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
13284
                                         Stmt *AStmt, SourceLocation StartLoc,
13285
0
                                         SourceLocation EndLoc) {
13286
0
  if (!AStmt)
13287
0
    return StmtError();
13288
13289
0
  auto *CS = cast<CapturedStmt>(AStmt);
13290
  // 1.2.2 OpenMP Language Terminology
13291
  // Structured block - An executable statement with a single entry at the
13292
  // top and a single exit at the bottom.
13293
  // The point of exit cannot be a branch out of the structured block.
13294
  // longjmp() and throw() must not violate the entry/exit criteria.
13295
0
  CS->getCapturedDecl()->setNothrow();
13296
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
13297
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
13298
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13299
    // 1.2.2 OpenMP Language Terminology
13300
    // Structured block - An executable statement with a single entry at the
13301
    // top and a single exit at the bottom.
13302
    // The point of exit cannot be a branch out of the structured block.
13303
    // longjmp() and throw() must not violate the entry/exit criteria.
13304
0
    CS->getCapturedDecl()->setNothrow();
13305
0
  }
13306
13307
0
  setFunctionHasBranchProtectedScope();
13308
13309
0
  return OMPTargetParallelDirective::Create(
13310
0
      Context, StartLoc, EndLoc, Clauses, AStmt,
13311
0
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13312
0
}
13313
13314
StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
13315
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13316
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13317
0
  if (!AStmt)
13318
0
    return StmtError();
13319
13320
0
  auto *CS = cast<CapturedStmt>(AStmt);
13321
  // 1.2.2 OpenMP Language Terminology
13322
  // Structured block - An executable statement with a single entry at the
13323
  // top and a single exit at the bottom.
13324
  // The point of exit cannot be a branch out of the structured block.
13325
  // longjmp() and throw() must not violate the entry/exit criteria.
13326
0
  CS->getCapturedDecl()->setNothrow();
13327
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13328
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
13329
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13330
    // 1.2.2 OpenMP Language Terminology
13331
    // Structured block - An executable statement with a single entry at the
13332
    // top and a single exit at the bottom.
13333
    // The point of exit cannot be a branch out of the structured block.
13334
    // longjmp() and throw() must not violate the entry/exit criteria.
13335
0
    CS->getCapturedDecl()->setNothrow();
13336
0
  }
13337
13338
0
  OMPLoopBasedDirective::HelperExprs B;
13339
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13340
  // define the nested loops number.
13341
0
  unsigned NestedLoopCount =
13342
0
      checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
13343
0
                      getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
13344
0
                      VarsWithImplicitDSA, B);
13345
0
  if (NestedLoopCount == 0)
13346
0
    return StmtError();
13347
13348
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13349
0
         "omp target parallel for loop exprs were not built");
13350
13351
0
  if (!CurContext->isDependentContext()) {
13352
    // Finalize the clauses that need pre-built expressions for CodeGen.
13353
0
    for (OMPClause *C : Clauses) {
13354
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
13355
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13356
0
                                     B.NumIterations, *this, CurScope,
13357
0
                                     DSAStack))
13358
0
          return StmtError();
13359
0
    }
13360
0
  }
13361
13362
0
  setFunctionHasBranchProtectedScope();
13363
0
  return OMPTargetParallelForDirective::Create(
13364
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13365
0
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13366
0
}
13367
13368
/// Check for existence of a map clause in the list of clauses.
13369
static bool hasClauses(ArrayRef<OMPClause *> Clauses,
13370
0
                       const OpenMPClauseKind K) {
13371
0
  return llvm::any_of(
13372
0
      Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
13373
0
}
13374
13375
template <typename... Params>
13376
static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
13377
0
                       const Params... ClauseTypes) {
13378
0
  return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
13379
0
}
Unexecuted instantiation: SemaOpenMP.cpp:bool hasClauses<llvm::omp::Clause>(llvm::ArrayRef<clang::OMPClause*>, llvm::omp::Clause, llvm::omp::Clause const)
Unexecuted instantiation: SemaOpenMP.cpp:bool hasClauses<llvm::omp::Clause, llvm::omp::Clause, llvm::omp::Clause>(llvm::ArrayRef<clang::OMPClause*>, llvm::omp::Clause, llvm::omp::Clause const, llvm::omp::Clause const, llvm::omp::Clause const)
Unexecuted instantiation: SemaOpenMP.cpp:bool hasClauses<llvm::omp::Clause, llvm::omp::Clause>(llvm::ArrayRef<clang::OMPClause*>, llvm::omp::Clause, llvm::omp::Clause const, llvm::omp::Clause const)
13380
13381
/// Check if the variables in the mapping clause are externally visible.
13382
0
static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) {
13383
0
  for (const OMPClause *C : Clauses) {
13384
0
    if (auto *TC = dyn_cast<OMPToClause>(C))
13385
0
      return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
13386
0
        return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13387
0
               (VD->isExternallyVisible() &&
13388
0
                VD->getVisibility() != HiddenVisibility);
13389
0
      });
13390
0
    else if (auto *FC = dyn_cast<OMPFromClause>(C))
13391
0
      return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
13392
0
        return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13393
0
               (VD->isExternallyVisible() &&
13394
0
                VD->getVisibility() != HiddenVisibility);
13395
0
      });
13396
0
  }
13397
13398
0
  return true;
13399
0
}
13400
13401
StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
13402
                                                Stmt *AStmt,
13403
                                                SourceLocation StartLoc,
13404
0
                                                SourceLocation EndLoc) {
13405
0
  if (!AStmt)
13406
0
    return StmtError();
13407
13408
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13409
13410
  // OpenMP [2.12.2, target data Construct, Restrictions]
13411
  // At least one map, use_device_addr or use_device_ptr clause must appear on
13412
  // the directive.
13413
0
  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13414
0
      (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
13415
0
    StringRef Expected;
13416
0
    if (LangOpts.OpenMP < 50)
13417
0
      Expected = "'map' or 'use_device_ptr'";
13418
0
    else
13419
0
      Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
13420
0
    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13421
0
        << Expected << getOpenMPDirectiveName(OMPD_target_data);
13422
0
    return StmtError();
13423
0
  }
13424
13425
0
  setFunctionHasBranchProtectedScope();
13426
13427
0
  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13428
0
                                        AStmt);
13429
0
}
13430
13431
StmtResult
13432
Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
13433
                                          SourceLocation StartLoc,
13434
0
                                          SourceLocation EndLoc, Stmt *AStmt) {
13435
0
  if (!AStmt)
13436
0
    return StmtError();
13437
13438
0
  auto *CS = cast<CapturedStmt>(AStmt);
13439
  // 1.2.2 OpenMP Language Terminology
13440
  // Structured block - An executable statement with a single entry at the
13441
  // top and a single exit at the bottom.
13442
  // The point of exit cannot be a branch out of the structured block.
13443
  // longjmp() and throw() must not violate the entry/exit criteria.
13444
0
  CS->getCapturedDecl()->setNothrow();
13445
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
13446
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
13447
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13448
    // 1.2.2 OpenMP Language Terminology
13449
    // Structured block - An executable statement with a single entry at the
13450
    // top and a single exit at the bottom.
13451
    // The point of exit cannot be a branch out of the structured block.
13452
    // longjmp() and throw() must not violate the entry/exit criteria.
13453
0
    CS->getCapturedDecl()->setNothrow();
13454
0
  }
13455
13456
  // OpenMP [2.10.2, Restrictions, p. 99]
13457
  // At least one map clause must appear on the directive.
13458
0
  if (!hasClauses(Clauses, OMPC_map)) {
13459
0
    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13460
0
        << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13461
0
    return StmtError();
13462
0
  }
13463
13464
0
  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13465
0
                                             AStmt);
13466
0
}
13467
13468
StmtResult
13469
Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
13470
                                         SourceLocation StartLoc,
13471
0
                                         SourceLocation EndLoc, Stmt *AStmt) {
13472
0
  if (!AStmt)
13473
0
    return StmtError();
13474
13475
0
  auto *CS = cast<CapturedStmt>(AStmt);
13476
  // 1.2.2 OpenMP Language Terminology
13477
  // Structured block - An executable statement with a single entry at the
13478
  // top and a single exit at the bottom.
13479
  // The point of exit cannot be a branch out of the structured block.
13480
  // longjmp() and throw() must not violate the entry/exit criteria.
13481
0
  CS->getCapturedDecl()->setNothrow();
13482
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
13483
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
13484
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13485
    // 1.2.2 OpenMP Language Terminology
13486
    // Structured block - An executable statement with a single entry at the
13487
    // top and a single exit at the bottom.
13488
    // The point of exit cannot be a branch out of the structured block.
13489
    // longjmp() and throw() must not violate the entry/exit criteria.
13490
0
    CS->getCapturedDecl()->setNothrow();
13491
0
  }
13492
13493
  // OpenMP [2.10.3, Restrictions, p. 102]
13494
  // At least one map clause must appear on the directive.
13495
0
  if (!hasClauses(Clauses, OMPC_map)) {
13496
0
    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13497
0
        << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13498
0
    return StmtError();
13499
0
  }
13500
13501
0
  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13502
0
                                            AStmt);
13503
0
}
13504
13505
StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
13506
                                                  SourceLocation StartLoc,
13507
                                                  SourceLocation EndLoc,
13508
0
                                                  Stmt *AStmt) {
13509
0
  if (!AStmt)
13510
0
    return StmtError();
13511
13512
0
  auto *CS = cast<CapturedStmt>(AStmt);
13513
  // 1.2.2 OpenMP Language Terminology
13514
  // Structured block - An executable statement with a single entry at the
13515
  // top and a single exit at the bottom.
13516
  // The point of exit cannot be a branch out of the structured block.
13517
  // longjmp() and throw() must not violate the entry/exit criteria.
13518
0
  CS->getCapturedDecl()->setNothrow();
13519
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
13520
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
13521
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13522
    // 1.2.2 OpenMP Language Terminology
13523
    // Structured block - An executable statement with a single entry at the
13524
    // top and a single exit at the bottom.
13525
    // The point of exit cannot be a branch out of the structured block.
13526
    // longjmp() and throw() must not violate the entry/exit criteria.
13527
0
    CS->getCapturedDecl()->setNothrow();
13528
0
  }
13529
13530
0
  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
13531
0
    Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13532
0
    return StmtError();
13533
0
  }
13534
13535
0
  if (!isClauseMappable(Clauses)) {
13536
0
    Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13537
0
    return StmtError();
13538
0
  }
13539
13540
0
  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
13541
0
                                          AStmt);
13542
0
}
13543
13544
StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
13545
                                           Stmt *AStmt, SourceLocation StartLoc,
13546
0
                                           SourceLocation EndLoc) {
13547
0
  if (!AStmt)
13548
0
    return StmtError();
13549
13550
  // Report affected OpenMP target offloading behavior when in HIP lang-mode.
13551
0
  if (getLangOpts().HIP && (DSAStack->getParentDirective() == OMPD_target))
13552
0
    Diag(StartLoc, diag::warn_hip_omp_target_directives);
13553
13554
0
  auto *CS = cast<CapturedStmt>(AStmt);
13555
  // 1.2.2 OpenMP Language Terminology
13556
  // Structured block - An executable statement with a single entry at the
13557
  // top and a single exit at the bottom.
13558
  // The point of exit cannot be a branch out of the structured block.
13559
  // longjmp() and throw() must not violate the entry/exit criteria.
13560
0
  CS->getCapturedDecl()->setNothrow();
13561
13562
0
  setFunctionHasBranchProtectedScope();
13563
13564
0
  DSAStack->setParentTeamsRegionLoc(StartLoc);
13565
13566
0
  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13567
0
}
13568
13569
StmtResult
13570
Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
13571
                                            SourceLocation EndLoc,
13572
0
                                            OpenMPDirectiveKind CancelRegion) {
13573
0
  if (DSAStack->isParentNowaitRegion()) {
13574
0
    Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13575
0
    return StmtError();
13576
0
  }
13577
0
  if (DSAStack->isParentOrderedRegion()) {
13578
0
    Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13579
0
    return StmtError();
13580
0
  }
13581
0
  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
13582
0
                                               CancelRegion);
13583
0
}
13584
13585
StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
13586
                                            SourceLocation StartLoc,
13587
                                            SourceLocation EndLoc,
13588
0
                                            OpenMPDirectiveKind CancelRegion) {
13589
0
  if (DSAStack->isParentNowaitRegion()) {
13590
0
    Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13591
0
    return StmtError();
13592
0
  }
13593
0
  if (DSAStack->isParentOrderedRegion()) {
13594
0
    Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13595
0
    return StmtError();
13596
0
  }
13597
0
  DSAStack->setParentCancelRegion(/*Cancel=*/true);
13598
0
  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
13599
0
                                    CancelRegion);
13600
0
}
13601
13602
static bool checkReductionClauseWithNogroup(Sema &S,
13603
0
                                            ArrayRef<OMPClause *> Clauses) {
13604
0
  const OMPClause *ReductionClause = nullptr;
13605
0
  const OMPClause *NogroupClause = nullptr;
13606
0
  for (const OMPClause *C : Clauses) {
13607
0
    if (C->getClauseKind() == OMPC_reduction) {
13608
0
      ReductionClause = C;
13609
0
      if (NogroupClause)
13610
0
        break;
13611
0
      continue;
13612
0
    }
13613
0
    if (C->getClauseKind() == OMPC_nogroup) {
13614
0
      NogroupClause = C;
13615
0
      if (ReductionClause)
13616
0
        break;
13617
0
      continue;
13618
0
    }
13619
0
  }
13620
0
  if (ReductionClause && NogroupClause) {
13621
0
    S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13622
0
        << SourceRange(NogroupClause->getBeginLoc(),
13623
0
                       NogroupClause->getEndLoc());
13624
0
    return true;
13625
0
  }
13626
0
  return false;
13627
0
}
13628
13629
StmtResult Sema::ActOnOpenMPTaskLoopDirective(
13630
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13631
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13632
0
  if (!AStmt)
13633
0
    return StmtError();
13634
13635
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13636
0
  OMPLoopBasedDirective::HelperExprs B;
13637
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13638
  // define the nested loops number.
13639
0
  unsigned NestedLoopCount =
13640
0
      checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
13641
0
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13642
0
                      VarsWithImplicitDSA, B);
13643
0
  if (NestedLoopCount == 0)
13644
0
    return StmtError();
13645
13646
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13647
0
         "omp for loop exprs were not built");
13648
13649
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13650
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13651
  // not appear on the same taskloop directive.
13652
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13653
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
13654
0
    return StmtError();
13655
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13656
  // If a reduction clause is present on the taskloop directive, the nogroup
13657
  // clause must not be specified.
13658
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
13659
0
    return StmtError();
13660
13661
0
  setFunctionHasBranchProtectedScope();
13662
0
  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13663
0
                                      NestedLoopCount, Clauses, AStmt, B,
13664
0
                                      DSAStack->isCancelRegion());
13665
0
}
13666
13667
StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
13668
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13669
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13670
0
  if (!AStmt)
13671
0
    return StmtError();
13672
13673
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13674
0
  OMPLoopBasedDirective::HelperExprs B;
13675
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13676
  // define the nested loops number.
13677
0
  unsigned NestedLoopCount =
13678
0
      checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
13679
0
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13680
0
                      VarsWithImplicitDSA, B);
13681
0
  if (NestedLoopCount == 0)
13682
0
    return StmtError();
13683
13684
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13685
0
         "omp for loop exprs were not built");
13686
13687
0
  if (!CurContext->isDependentContext()) {
13688
    // Finalize the clauses that need pre-built expressions for CodeGen.
13689
0
    for (OMPClause *C : Clauses) {
13690
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
13691
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13692
0
                                     B.NumIterations, *this, CurScope,
13693
0
                                     DSAStack))
13694
0
          return StmtError();
13695
0
    }
13696
0
  }
13697
13698
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13699
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13700
  // not appear on the same taskloop directive.
13701
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13702
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
13703
0
    return StmtError();
13704
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13705
  // If a reduction clause is present on the taskloop directive, the nogroup
13706
  // clause must not be specified.
13707
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
13708
0
    return StmtError();
13709
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
13710
0
    return StmtError();
13711
13712
0
  setFunctionHasBranchProtectedScope();
13713
0
  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13714
0
                                          NestedLoopCount, Clauses, AStmt, B);
13715
0
}
13716
13717
StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
13718
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13719
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13720
0
  if (!AStmt)
13721
0
    return StmtError();
13722
13723
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13724
0
  OMPLoopBasedDirective::HelperExprs B;
13725
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13726
  // define the nested loops number.
13727
0
  unsigned NestedLoopCount =
13728
0
      checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13729
0
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13730
0
                      VarsWithImplicitDSA, B);
13731
0
  if (NestedLoopCount == 0)
13732
0
    return StmtError();
13733
13734
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13735
0
         "omp for loop exprs were not built");
13736
13737
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13738
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13739
  // not appear on the same taskloop directive.
13740
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13741
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
13742
0
    return StmtError();
13743
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13744
  // If a reduction clause is present on the taskloop directive, the nogroup
13745
  // clause must not be specified.
13746
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
13747
0
    return StmtError();
13748
13749
0
  setFunctionHasBranchProtectedScope();
13750
0
  return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13751
0
                                            NestedLoopCount, Clauses, AStmt, B,
13752
0
                                            DSAStack->isCancelRegion());
13753
0
}
13754
13755
StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective(
13756
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13757
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13758
0
  if (!AStmt)
13759
0
    return StmtError();
13760
13761
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13762
0
  OMPLoopBasedDirective::HelperExprs B;
13763
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13764
  // define the nested loops number.
13765
0
  unsigned NestedLoopCount =
13766
0
      checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses),
13767
0
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13768
0
                      VarsWithImplicitDSA, B);
13769
0
  if (NestedLoopCount == 0)
13770
0
    return StmtError();
13771
13772
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13773
0
         "omp for loop exprs were not built");
13774
13775
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13776
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13777
  // not appear on the same taskloop directive.
13778
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13779
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
13780
0
    return StmtError();
13781
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13782
  // If a reduction clause is present on the taskloop directive, the nogroup
13783
  // clause must not be specified.
13784
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
13785
0
    return StmtError();
13786
13787
0
  setFunctionHasBranchProtectedScope();
13788
0
  return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13789
0
                                            NestedLoopCount, Clauses, AStmt, B,
13790
0
                                            DSAStack->isCancelRegion());
13791
0
}
13792
13793
StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
13794
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13795
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13796
0
  if (!AStmt)
13797
0
    return StmtError();
13798
13799
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13800
0
  OMPLoopBasedDirective::HelperExprs B;
13801
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13802
  // define the nested loops number.
13803
0
  unsigned NestedLoopCount =
13804
0
      checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13805
0
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13806
0
                      VarsWithImplicitDSA, B);
13807
0
  if (NestedLoopCount == 0)
13808
0
    return StmtError();
13809
13810
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13811
0
         "omp for loop exprs were not built");
13812
13813
0
  if (!CurContext->isDependentContext()) {
13814
    // Finalize the clauses that need pre-built expressions for CodeGen.
13815
0
    for (OMPClause *C : Clauses) {
13816
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
13817
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13818
0
                                     B.NumIterations, *this, CurScope,
13819
0
                                     DSAStack))
13820
0
          return StmtError();
13821
0
    }
13822
0
  }
13823
13824
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13825
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13826
  // not appear on the same taskloop directive.
13827
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13828
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
13829
0
    return StmtError();
13830
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13831
  // If a reduction clause is present on the taskloop directive, the nogroup
13832
  // clause must not be specified.
13833
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
13834
0
    return StmtError();
13835
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
13836
0
    return StmtError();
13837
13838
0
  setFunctionHasBranchProtectedScope();
13839
0
  return OMPMasterTaskLoopSimdDirective::Create(
13840
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13841
0
}
13842
13843
StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective(
13844
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13845
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13846
0
  if (!AStmt)
13847
0
    return StmtError();
13848
13849
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13850
0
  OMPLoopBasedDirective::HelperExprs B;
13851
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13852
  // define the nested loops number.
13853
0
  unsigned NestedLoopCount =
13854
0
      checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13855
0
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13856
0
                      VarsWithImplicitDSA, B);
13857
0
  if (NestedLoopCount == 0)
13858
0
    return StmtError();
13859
13860
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13861
0
         "omp for loop exprs were not built");
13862
13863
0
  if (!CurContext->isDependentContext()) {
13864
    // Finalize the clauses that need pre-built expressions for CodeGen.
13865
0
    for (OMPClause *C : Clauses) {
13866
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
13867
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13868
0
                                     B.NumIterations, *this, CurScope,
13869
0
                                     DSAStack))
13870
0
          return StmtError();
13871
0
    }
13872
0
  }
13873
13874
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13875
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13876
  // not appear on the same taskloop directive.
13877
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13878
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
13879
0
    return StmtError();
13880
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13881
  // If a reduction clause is present on the taskloop directive, the nogroup
13882
  // clause must not be specified.
13883
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
13884
0
    return StmtError();
13885
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
13886
0
    return StmtError();
13887
13888
0
  setFunctionHasBranchProtectedScope();
13889
0
  return OMPMaskedTaskLoopSimdDirective::Create(
13890
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13891
0
}
13892
13893
StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
13894
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13895
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13896
0
  if (!AStmt)
13897
0
    return StmtError();
13898
13899
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13900
0
  auto *CS = cast<CapturedStmt>(AStmt);
13901
  // 1.2.2 OpenMP Language Terminology
13902
  // Structured block - An executable statement with a single entry at the
13903
  // top and a single exit at the bottom.
13904
  // The point of exit cannot be a branch out of the structured block.
13905
  // longjmp() and throw() must not violate the entry/exit criteria.
13906
0
  CS->getCapturedDecl()->setNothrow();
13907
0
  for (int ThisCaptureLevel =
13908
0
           getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13909
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
13910
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13911
    // 1.2.2 OpenMP Language Terminology
13912
    // Structured block - An executable statement with a single entry at the
13913
    // top and a single exit at the bottom.
13914
    // The point of exit cannot be a branch out of the structured block.
13915
    // longjmp() and throw() must not violate the entry/exit criteria.
13916
0
    CS->getCapturedDecl()->setNothrow();
13917
0
  }
13918
13919
0
  OMPLoopBasedDirective::HelperExprs B;
13920
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13921
  // define the nested loops number.
13922
0
  unsigned NestedLoopCount = checkOpenMPLoop(
13923
0
      OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13924
0
      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13925
0
      VarsWithImplicitDSA, B);
13926
0
  if (NestedLoopCount == 0)
13927
0
    return StmtError();
13928
13929
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13930
0
         "omp for loop exprs were not built");
13931
13932
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13933
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13934
  // not appear on the same taskloop directive.
13935
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13936
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
13937
0
    return StmtError();
13938
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13939
  // If a reduction clause is present on the taskloop directive, the nogroup
13940
  // clause must not be specified.
13941
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
13942
0
    return StmtError();
13943
13944
0
  setFunctionHasBranchProtectedScope();
13945
0
  return OMPParallelMasterTaskLoopDirective::Create(
13946
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13947
0
      DSAStack->isCancelRegion());
13948
0
}
13949
13950
StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective(
13951
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13952
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13953
0
  if (!AStmt)
13954
0
    return StmtError();
13955
13956
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13957
0
  auto *CS = cast<CapturedStmt>(AStmt);
13958
  // 1.2.2 OpenMP Language Terminology
13959
  // Structured block - An executable statement with a single entry at the
13960
  // top and a single exit at the bottom.
13961
  // The point of exit cannot be a branch out of the structured block.
13962
  // longjmp() and throw() must not violate the entry/exit criteria.
13963
0
  CS->getCapturedDecl()->setNothrow();
13964
0
  for (int ThisCaptureLevel =
13965
0
           getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop);
13966
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
13967
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13968
    // 1.2.2 OpenMP Language Terminology
13969
    // Structured block - An executable statement with a single entry at the
13970
    // top and a single exit at the bottom.
13971
    // The point of exit cannot be a branch out of the structured block.
13972
    // longjmp() and throw() must not violate the entry/exit criteria.
13973
0
    CS->getCapturedDecl()->setNothrow();
13974
0
  }
13975
13976
0
  OMPLoopBasedDirective::HelperExprs B;
13977
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13978
  // define the nested loops number.
13979
0
  unsigned NestedLoopCount = checkOpenMPLoop(
13980
0
      OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses),
13981
0
      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13982
0
      VarsWithImplicitDSA, B);
13983
0
  if (NestedLoopCount == 0)
13984
0
    return StmtError();
13985
13986
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13987
0
         "omp for loop exprs were not built");
13988
13989
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13990
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13991
  // not appear on the same taskloop directive.
13992
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13993
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
13994
0
    return StmtError();
13995
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13996
  // If a reduction clause is present on the taskloop directive, the nogroup
13997
  // clause must not be specified.
13998
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
13999
0
    return StmtError();
14000
14001
0
  setFunctionHasBranchProtectedScope();
14002
0
  return OMPParallelMaskedTaskLoopDirective::Create(
14003
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14004
0
      DSAStack->isCancelRegion());
14005
0
}
14006
14007
StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
14008
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14009
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14010
0
  if (!AStmt)
14011
0
    return StmtError();
14012
14013
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14014
0
  auto *CS = cast<CapturedStmt>(AStmt);
14015
  // 1.2.2 OpenMP Language Terminology
14016
  // Structured block - An executable statement with a single entry at the
14017
  // top and a single exit at the bottom.
14018
  // The point of exit cannot be a branch out of the structured block.
14019
  // longjmp() and throw() must not violate the entry/exit criteria.
14020
0
  CS->getCapturedDecl()->setNothrow();
14021
0
  for (int ThisCaptureLevel =
14022
0
           getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
14023
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14024
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14025
    // 1.2.2 OpenMP Language Terminology
14026
    // Structured block - An executable statement with a single entry at the
14027
    // top and a single exit at the bottom.
14028
    // The point of exit cannot be a branch out of the structured block.
14029
    // longjmp() and throw() must not violate the entry/exit criteria.
14030
0
    CS->getCapturedDecl()->setNothrow();
14031
0
  }
14032
14033
0
  OMPLoopBasedDirective::HelperExprs B;
14034
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14035
  // define the nested loops number.
14036
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14037
0
      OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
14038
0
      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
14039
0
      VarsWithImplicitDSA, B);
14040
0
  if (NestedLoopCount == 0)
14041
0
    return StmtError();
14042
14043
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14044
0
         "omp for loop exprs were not built");
14045
14046
0
  if (!CurContext->isDependentContext()) {
14047
    // Finalize the clauses that need pre-built expressions for CodeGen.
14048
0
    for (OMPClause *C : Clauses) {
14049
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14050
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14051
0
                                     B.NumIterations, *this, CurScope,
14052
0
                                     DSAStack))
14053
0
          return StmtError();
14054
0
    }
14055
0
  }
14056
14057
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14058
  // The grainsize clause and num_tasks clause are mutually exclusive and may
14059
  // not appear on the same taskloop directive.
14060
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
14061
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
14062
0
    return StmtError();
14063
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14064
  // If a reduction clause is present on the taskloop directive, the nogroup
14065
  // clause must not be specified.
14066
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
14067
0
    return StmtError();
14068
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14069
0
    return StmtError();
14070
14071
0
  setFunctionHasBranchProtectedScope();
14072
0
  return OMPParallelMasterTaskLoopSimdDirective::Create(
14073
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14074
0
}
14075
14076
StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
14077
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14078
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14079
0
  if (!AStmt)
14080
0
    return StmtError();
14081
14082
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14083
0
  auto *CS = cast<CapturedStmt>(AStmt);
14084
  // 1.2.2 OpenMP Language Terminology
14085
  // Structured block - An executable statement with a single entry at the
14086
  // top and a single exit at the bottom.
14087
  // The point of exit cannot be a branch out of the structured block.
14088
  // longjmp() and throw() must not violate the entry/exit criteria.
14089
0
  CS->getCapturedDecl()->setNothrow();
14090
0
  for (int ThisCaptureLevel =
14091
0
           getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd);
14092
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14093
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14094
    // 1.2.2 OpenMP Language Terminology
14095
    // Structured block - An executable statement with a single entry at the
14096
    // top and a single exit at the bottom.
14097
    // The point of exit cannot be a branch out of the structured block.
14098
    // longjmp() and throw() must not violate the entry/exit criteria.
14099
0
    CS->getCapturedDecl()->setNothrow();
14100
0
  }
14101
14102
0
  OMPLoopBasedDirective::HelperExprs B;
14103
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14104
  // define the nested loops number.
14105
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14106
0
      OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
14107
0
      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
14108
0
      VarsWithImplicitDSA, B);
14109
0
  if (NestedLoopCount == 0)
14110
0
    return StmtError();
14111
14112
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14113
0
         "omp for loop exprs were not built");
14114
14115
0
  if (!CurContext->isDependentContext()) {
14116
    // Finalize the clauses that need pre-built expressions for CodeGen.
14117
0
    for (OMPClause *C : Clauses) {
14118
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14119
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14120
0
                                     B.NumIterations, *this, CurScope,
14121
0
                                     DSAStack))
14122
0
          return StmtError();
14123
0
    }
14124
0
  }
14125
14126
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14127
  // The grainsize clause and num_tasks clause are mutually exclusive and may
14128
  // not appear on the same taskloop directive.
14129
0
  if (checkMutuallyExclusiveClauses(*this, Clauses,
14130
0
                                    {OMPC_grainsize, OMPC_num_tasks}))
14131
0
    return StmtError();
14132
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14133
  // If a reduction clause is present on the taskloop directive, the nogroup
14134
  // clause must not be specified.
14135
0
  if (checkReductionClauseWithNogroup(*this, Clauses))
14136
0
    return StmtError();
14137
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14138
0
    return StmtError();
14139
14140
0
  setFunctionHasBranchProtectedScope();
14141
0
  return OMPParallelMaskedTaskLoopSimdDirective::Create(
14142
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14143
0
}
14144
14145
StmtResult Sema::ActOnOpenMPDistributeDirective(
14146
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14147
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14148
0
  if (!AStmt)
14149
0
    return StmtError();
14150
14151
0
  if (!checkLastPrivateForMappedDirectives(Clauses))
14152
0
    return StmtError();
14153
14154
0
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14155
0
  OMPLoopBasedDirective::HelperExprs B;
14156
  // In presence of clause 'collapse' with number of loops, it will
14157
  // define the nested loops number.
14158
0
  unsigned NestedLoopCount =
14159
0
      checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
14160
0
                      nullptr /*ordered not a clause on distribute*/, AStmt,
14161
0
                      *this, *DSAStack, VarsWithImplicitDSA, B);
14162
0
  if (NestedLoopCount == 0)
14163
0
    return StmtError();
14164
14165
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14166
0
         "omp for loop exprs were not built");
14167
14168
0
  setFunctionHasBranchProtectedScope();
14169
0
  auto *DistributeDirective = OMPDistributeDirective::Create(
14170
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14171
0
      DSAStack->getMappedDirective());
14172
0
  return DistributeDirective;
14173
0
}
14174
14175
StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
14176
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14177
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14178
0
  if (!AStmt)
14179
0
    return StmtError();
14180
14181
0
  auto *CS = cast<CapturedStmt>(AStmt);
14182
  // 1.2.2 OpenMP Language Terminology
14183
  // Structured block - An executable statement with a single entry at the
14184
  // top and a single exit at the bottom.
14185
  // The point of exit cannot be a branch out of the structured block.
14186
  // longjmp() and throw() must not violate the entry/exit criteria.
14187
0
  CS->getCapturedDecl()->setNothrow();
14188
0
  for (int ThisCaptureLevel =
14189
0
           getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
14190
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14191
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14192
    // 1.2.2 OpenMP Language Terminology
14193
    // Structured block - An executable statement with a single entry at the
14194
    // top and a single exit at the bottom.
14195
    // The point of exit cannot be a branch out of the structured block.
14196
    // longjmp() and throw() must not violate the entry/exit criteria.
14197
0
    CS->getCapturedDecl()->setNothrow();
14198
0
  }
14199
14200
0
  OMPLoopBasedDirective::HelperExprs B;
14201
  // In presence of clause 'collapse' with number of loops, it will
14202
  // define the nested loops number.
14203
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14204
0
      OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14205
0
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14206
0
      VarsWithImplicitDSA, B);
14207
0
  if (NestedLoopCount == 0)
14208
0
    return StmtError();
14209
14210
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14211
0
         "omp for loop exprs were not built");
14212
14213
0
  setFunctionHasBranchProtectedScope();
14214
0
  return OMPDistributeParallelForDirective::Create(
14215
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14216
0
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14217
0
}
14218
14219
StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
14220
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14221
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14222
0
  if (!AStmt)
14223
0
    return StmtError();
14224
14225
0
  auto *CS = cast<CapturedStmt>(AStmt);
14226
  // 1.2.2 OpenMP Language Terminology
14227
  // Structured block - An executable statement with a single entry at the
14228
  // top and a single exit at the bottom.
14229
  // The point of exit cannot be a branch out of the structured block.
14230
  // longjmp() and throw() must not violate the entry/exit criteria.
14231
0
  CS->getCapturedDecl()->setNothrow();
14232
0
  for (int ThisCaptureLevel =
14233
0
           getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
14234
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14235
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14236
    // 1.2.2 OpenMP Language Terminology
14237
    // Structured block - An executable statement with a single entry at the
14238
    // top and a single exit at the bottom.
14239
    // The point of exit cannot be a branch out of the structured block.
14240
    // longjmp() and throw() must not violate the entry/exit criteria.
14241
0
    CS->getCapturedDecl()->setNothrow();
14242
0
  }
14243
14244
0
  OMPLoopBasedDirective::HelperExprs B;
14245
  // In presence of clause 'collapse' with number of loops, it will
14246
  // define the nested loops number.
14247
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14248
0
      OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14249
0
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14250
0
      VarsWithImplicitDSA, B);
14251
0
  if (NestedLoopCount == 0)
14252
0
    return StmtError();
14253
14254
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14255
0
         "omp for loop exprs were not built");
14256
14257
0
  if (!CurContext->isDependentContext()) {
14258
    // Finalize the clauses that need pre-built expressions for CodeGen.
14259
0
    for (OMPClause *C : Clauses) {
14260
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14261
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14262
0
                                     B.NumIterations, *this, CurScope,
14263
0
                                     DSAStack))
14264
0
          return StmtError();
14265
0
    }
14266
0
  }
14267
14268
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14269
0
    return StmtError();
14270
14271
0
  setFunctionHasBranchProtectedScope();
14272
0
  return OMPDistributeParallelForSimdDirective::Create(
14273
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14274
0
}
14275
14276
StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
14277
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14278
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14279
0
  if (!AStmt)
14280
0
    return StmtError();
14281
14282
0
  auto *CS = cast<CapturedStmt>(AStmt);
14283
  // 1.2.2 OpenMP Language Terminology
14284
  // Structured block - An executable statement with a single entry at the
14285
  // top and a single exit at the bottom.
14286
  // The point of exit cannot be a branch out of the structured block.
14287
  // longjmp() and throw() must not violate the entry/exit criteria.
14288
0
  CS->getCapturedDecl()->setNothrow();
14289
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
14290
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14291
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14292
    // 1.2.2 OpenMP Language Terminology
14293
    // Structured block - An executable statement with a single entry at the
14294
    // top and a single exit at the bottom.
14295
    // The point of exit cannot be a branch out of the structured block.
14296
    // longjmp() and throw() must not violate the entry/exit criteria.
14297
0
    CS->getCapturedDecl()->setNothrow();
14298
0
  }
14299
14300
0
  OMPLoopBasedDirective::HelperExprs B;
14301
  // In presence of clause 'collapse' with number of loops, it will
14302
  // define the nested loops number.
14303
0
  unsigned NestedLoopCount =
14304
0
      checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
14305
0
                      nullptr /*ordered not a clause on distribute*/, CS, *this,
14306
0
                      *DSAStack, VarsWithImplicitDSA, B);
14307
0
  if (NestedLoopCount == 0)
14308
0
    return StmtError();
14309
14310
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14311
0
         "omp for loop exprs were not built");
14312
14313
0
  if (!CurContext->isDependentContext()) {
14314
    // Finalize the clauses that need pre-built expressions for CodeGen.
14315
0
    for (OMPClause *C : Clauses) {
14316
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14317
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14318
0
                                     B.NumIterations, *this, CurScope,
14319
0
                                     DSAStack))
14320
0
          return StmtError();
14321
0
    }
14322
0
  }
14323
14324
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14325
0
    return StmtError();
14326
14327
0
  setFunctionHasBranchProtectedScope();
14328
0
  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
14329
0
                                            NestedLoopCount, Clauses, AStmt, B);
14330
0
}
14331
14332
StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
14333
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14334
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14335
0
  if (!AStmt)
14336
0
    return StmtError();
14337
14338
0
  auto *CS = cast<CapturedStmt>(AStmt);
14339
  // 1.2.2 OpenMP Language Terminology
14340
  // Structured block - An executable statement with a single entry at the
14341
  // top and a single exit at the bottom.
14342
  // The point of exit cannot be a branch out of the structured block.
14343
  // longjmp() and throw() must not violate the entry/exit criteria.
14344
0
  CS->getCapturedDecl()->setNothrow();
14345
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
14346
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14347
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14348
    // 1.2.2 OpenMP Language Terminology
14349
    // Structured block - An executable statement with a single entry at the
14350
    // top and a single exit at the bottom.
14351
    // The point of exit cannot be a branch out of the structured block.
14352
    // longjmp() and throw() must not violate the entry/exit criteria.
14353
0
    CS->getCapturedDecl()->setNothrow();
14354
0
  }
14355
14356
0
  OMPLoopBasedDirective::HelperExprs B;
14357
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14358
  // define the nested loops number.
14359
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14360
0
      OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
14361
0
      getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA,
14362
0
      B);
14363
0
  if (NestedLoopCount == 0)
14364
0
    return StmtError();
14365
14366
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14367
0
         "omp target parallel for simd loop exprs were not built");
14368
14369
0
  if (!CurContext->isDependentContext()) {
14370
    // Finalize the clauses that need pre-built expressions for CodeGen.
14371
0
    for (OMPClause *C : Clauses) {
14372
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14373
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14374
0
                                     B.NumIterations, *this, CurScope,
14375
0
                                     DSAStack))
14376
0
          return StmtError();
14377
0
    }
14378
0
  }
14379
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14380
0
    return StmtError();
14381
14382
0
  setFunctionHasBranchProtectedScope();
14383
0
  return OMPTargetParallelForSimdDirective::Create(
14384
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14385
0
}
14386
14387
StmtResult Sema::ActOnOpenMPTargetSimdDirective(
14388
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14389
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14390
0
  if (!AStmt)
14391
0
    return StmtError();
14392
14393
0
  auto *CS = cast<CapturedStmt>(AStmt);
14394
  // 1.2.2 OpenMP Language Terminology
14395
  // Structured block - An executable statement with a single entry at the
14396
  // top and a single exit at the bottom.
14397
  // The point of exit cannot be a branch out of the structured block.
14398
  // longjmp() and throw() must not violate the entry/exit criteria.
14399
0
  CS->getCapturedDecl()->setNothrow();
14400
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
14401
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14402
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14403
    // 1.2.2 OpenMP Language Terminology
14404
    // Structured block - An executable statement with a single entry at the
14405
    // top and a single exit at the bottom.
14406
    // The point of exit cannot be a branch out of the structured block.
14407
    // longjmp() and throw() must not violate the entry/exit criteria.
14408
0
    CS->getCapturedDecl()->setNothrow();
14409
0
  }
14410
14411
0
  OMPLoopBasedDirective::HelperExprs B;
14412
  // In presence of clause 'collapse' with number of loops, it will define the
14413
  // nested loops number.
14414
0
  unsigned NestedLoopCount =
14415
0
      checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
14416
0
                      getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
14417
0
                      VarsWithImplicitDSA, B);
14418
0
  if (NestedLoopCount == 0)
14419
0
    return StmtError();
14420
14421
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14422
0
         "omp target simd loop exprs were not built");
14423
14424
0
  if (!CurContext->isDependentContext()) {
14425
    // Finalize the clauses that need pre-built expressions for CodeGen.
14426
0
    for (OMPClause *C : Clauses) {
14427
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14428
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14429
0
                                     B.NumIterations, *this, CurScope,
14430
0
                                     DSAStack))
14431
0
          return StmtError();
14432
0
    }
14433
0
  }
14434
14435
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14436
0
    return StmtError();
14437
14438
0
  setFunctionHasBranchProtectedScope();
14439
0
  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
14440
0
                                        NestedLoopCount, Clauses, AStmt, B);
14441
0
}
14442
14443
StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
14444
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14445
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14446
0
  if (!AStmt)
14447
0
    return StmtError();
14448
14449
0
  auto *CS = cast<CapturedStmt>(AStmt);
14450
  // 1.2.2 OpenMP Language Terminology
14451
  // Structured block - An executable statement with a single entry at the
14452
  // top and a single exit at the bottom.
14453
  // The point of exit cannot be a branch out of the structured block.
14454
  // longjmp() and throw() must not violate the entry/exit criteria.
14455
0
  CS->getCapturedDecl()->setNothrow();
14456
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
14457
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14458
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14459
    // 1.2.2 OpenMP Language Terminology
14460
    // Structured block - An executable statement with a single entry at the
14461
    // top and a single exit at the bottom.
14462
    // The point of exit cannot be a branch out of the structured block.
14463
    // longjmp() and throw() must not violate the entry/exit criteria.
14464
0
    CS->getCapturedDecl()->setNothrow();
14465
0
  }
14466
14467
0
  OMPLoopBasedDirective::HelperExprs B;
14468
  // In presence of clause 'collapse' with number of loops, it will
14469
  // define the nested loops number.
14470
0
  unsigned NestedLoopCount =
14471
0
      checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
14472
0
                      nullptr /*ordered not a clause on distribute*/, CS, *this,
14473
0
                      *DSAStack, VarsWithImplicitDSA, B);
14474
0
  if (NestedLoopCount == 0)
14475
0
    return StmtError();
14476
14477
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14478
0
         "omp teams distribute loop exprs were not built");
14479
14480
0
  setFunctionHasBranchProtectedScope();
14481
14482
0
  DSAStack->setParentTeamsRegionLoc(StartLoc);
14483
14484
0
  return OMPTeamsDistributeDirective::Create(
14485
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14486
0
}
14487
14488
StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
14489
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14490
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14491
0
  if (!AStmt)
14492
0
    return StmtError();
14493
14494
0
  auto *CS = cast<CapturedStmt>(AStmt);
14495
  // 1.2.2 OpenMP Language Terminology
14496
  // Structured block - An executable statement with a single entry at the
14497
  // top and a single exit at the bottom.
14498
  // The point of exit cannot be a branch out of the structured block.
14499
  // longjmp() and throw() must not violate the entry/exit criteria.
14500
0
  CS->getCapturedDecl()->setNothrow();
14501
0
  for (int ThisCaptureLevel =
14502
0
           getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
14503
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14504
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14505
    // 1.2.2 OpenMP Language Terminology
14506
    // Structured block - An executable statement with a single entry at the
14507
    // top and a single exit at the bottom.
14508
    // The point of exit cannot be a branch out of the structured block.
14509
    // longjmp() and throw() must not violate the entry/exit criteria.
14510
0
    CS->getCapturedDecl()->setNothrow();
14511
0
  }
14512
14513
0
  OMPLoopBasedDirective::HelperExprs B;
14514
  // In presence of clause 'collapse' with number of loops, it will
14515
  // define the nested loops number.
14516
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14517
0
      OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14518
0
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14519
0
      VarsWithImplicitDSA, B);
14520
14521
0
  if (NestedLoopCount == 0)
14522
0
    return StmtError();
14523
14524
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14525
0
         "omp teams distribute simd loop exprs were not built");
14526
14527
0
  if (!CurContext->isDependentContext()) {
14528
    // Finalize the clauses that need pre-built expressions for CodeGen.
14529
0
    for (OMPClause *C : Clauses) {
14530
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14531
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14532
0
                                     B.NumIterations, *this, CurScope,
14533
0
                                     DSAStack))
14534
0
          return StmtError();
14535
0
    }
14536
0
  }
14537
14538
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14539
0
    return StmtError();
14540
14541
0
  setFunctionHasBranchProtectedScope();
14542
14543
0
  DSAStack->setParentTeamsRegionLoc(StartLoc);
14544
14545
0
  return OMPTeamsDistributeSimdDirective::Create(
14546
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14547
0
}
14548
14549
StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
14550
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14551
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14552
0
  if (!AStmt)
14553
0
    return StmtError();
14554
14555
0
  auto *CS = cast<CapturedStmt>(AStmt);
14556
  // 1.2.2 OpenMP Language Terminology
14557
  // Structured block - An executable statement with a single entry at the
14558
  // top and a single exit at the bottom.
14559
  // The point of exit cannot be a branch out of the structured block.
14560
  // longjmp() and throw() must not violate the entry/exit criteria.
14561
0
  CS->getCapturedDecl()->setNothrow();
14562
14563
0
  for (int ThisCaptureLevel =
14564
0
           getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
14565
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14566
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14567
    // 1.2.2 OpenMP Language Terminology
14568
    // Structured block - An executable statement with a single entry at the
14569
    // top and a single exit at the bottom.
14570
    // The point of exit cannot be a branch out of the structured block.
14571
    // longjmp() and throw() must not violate the entry/exit criteria.
14572
0
    CS->getCapturedDecl()->setNothrow();
14573
0
  }
14574
14575
0
  OMPLoopBasedDirective::HelperExprs B;
14576
  // In presence of clause 'collapse' with number of loops, it will
14577
  // define the nested loops number.
14578
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14579
0
      OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14580
0
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14581
0
      VarsWithImplicitDSA, B);
14582
14583
0
  if (NestedLoopCount == 0)
14584
0
    return StmtError();
14585
14586
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14587
0
         "omp for loop exprs were not built");
14588
14589
0
  if (!CurContext->isDependentContext()) {
14590
    // Finalize the clauses that need pre-built expressions for CodeGen.
14591
0
    for (OMPClause *C : Clauses) {
14592
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14593
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14594
0
                                     B.NumIterations, *this, CurScope,
14595
0
                                     DSAStack))
14596
0
          return StmtError();
14597
0
    }
14598
0
  }
14599
14600
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14601
0
    return StmtError();
14602
14603
0
  setFunctionHasBranchProtectedScope();
14604
14605
0
  DSAStack->setParentTeamsRegionLoc(StartLoc);
14606
14607
0
  return OMPTeamsDistributeParallelForSimdDirective::Create(
14608
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14609
0
}
14610
14611
StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
14612
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14613
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14614
0
  if (!AStmt)
14615
0
    return StmtError();
14616
14617
0
  auto *CS = cast<CapturedStmt>(AStmt);
14618
  // 1.2.2 OpenMP Language Terminology
14619
  // Structured block - An executable statement with a single entry at the
14620
  // top and a single exit at the bottom.
14621
  // The point of exit cannot be a branch out of the structured block.
14622
  // longjmp() and throw() must not violate the entry/exit criteria.
14623
0
  CS->getCapturedDecl()->setNothrow();
14624
14625
0
  for (int ThisCaptureLevel =
14626
0
           getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
14627
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14628
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14629
    // 1.2.2 OpenMP Language Terminology
14630
    // Structured block - An executable statement with a single entry at the
14631
    // top and a single exit at the bottom.
14632
    // The point of exit cannot be a branch out of the structured block.
14633
    // longjmp() and throw() must not violate the entry/exit criteria.
14634
0
    CS->getCapturedDecl()->setNothrow();
14635
0
  }
14636
14637
0
  OMPLoopBasedDirective::HelperExprs B;
14638
  // In presence of clause 'collapse' with number of loops, it will
14639
  // define the nested loops number.
14640
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14641
0
      OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14642
0
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14643
0
      VarsWithImplicitDSA, B);
14644
14645
0
  if (NestedLoopCount == 0)
14646
0
    return StmtError();
14647
14648
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14649
0
         "omp for loop exprs were not built");
14650
14651
0
  setFunctionHasBranchProtectedScope();
14652
14653
0
  DSAStack->setParentTeamsRegionLoc(StartLoc);
14654
14655
0
  return OMPTeamsDistributeParallelForDirective::Create(
14656
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14657
0
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14658
0
}
14659
14660
StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
14661
                                                 Stmt *AStmt,
14662
                                                 SourceLocation StartLoc,
14663
0
                                                 SourceLocation EndLoc) {
14664
0
  if (!AStmt)
14665
0
    return StmtError();
14666
14667
0
  auto *CS = cast<CapturedStmt>(AStmt);
14668
  // 1.2.2 OpenMP Language Terminology
14669
  // Structured block - An executable statement with a single entry at the
14670
  // top and a single exit at the bottom.
14671
  // The point of exit cannot be a branch out of the structured block.
14672
  // longjmp() and throw() must not violate the entry/exit criteria.
14673
0
  CS->getCapturedDecl()->setNothrow();
14674
14675
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
14676
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14677
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14678
    // 1.2.2 OpenMP Language Terminology
14679
    // Structured block - An executable statement with a single entry at the
14680
    // top and a single exit at the bottom.
14681
    // The point of exit cannot be a branch out of the structured block.
14682
    // longjmp() and throw() must not violate the entry/exit criteria.
14683
0
    CS->getCapturedDecl()->setNothrow();
14684
0
  }
14685
0
  setFunctionHasBranchProtectedScope();
14686
14687
0
  const OMPClause *BareClause = nullptr;
14688
0
  bool HasThreadLimitAndNumTeamsClause = hasClauses(Clauses, OMPC_num_teams) &&
14689
0
                                         hasClauses(Clauses, OMPC_thread_limit);
14690
0
  bool HasBareClause = llvm::any_of(Clauses, [&](const OMPClause *C) {
14691
0
    BareClause = C;
14692
0
    return C->getClauseKind() == OMPC_ompx_bare;
14693
0
  });
14694
14695
0
  if (HasBareClause && !HasThreadLimitAndNumTeamsClause) {
14696
0
    Diag(BareClause->getBeginLoc(), diag::err_ompx_bare_no_grid);
14697
0
    return StmtError();
14698
0
  }
14699
14700
0
  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
14701
0
                                         AStmt);
14702
0
}
14703
14704
StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
14705
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14706
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14707
0
  if (!AStmt)
14708
0
    return StmtError();
14709
14710
0
  auto *CS = cast<CapturedStmt>(AStmt);
14711
  // 1.2.2 OpenMP Language Terminology
14712
  // Structured block - An executable statement with a single entry at the
14713
  // top and a single exit at the bottom.
14714
  // The point of exit cannot be a branch out of the structured block.
14715
  // longjmp() and throw() must not violate the entry/exit criteria.
14716
0
  CS->getCapturedDecl()->setNothrow();
14717
0
  for (int ThisCaptureLevel =
14718
0
           getOpenMPCaptureLevels(OMPD_target_teams_distribute);
14719
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14720
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14721
    // 1.2.2 OpenMP Language Terminology
14722
    // Structured block - An executable statement with a single entry at the
14723
    // top and a single exit at the bottom.
14724
    // The point of exit cannot be a branch out of the structured block.
14725
    // longjmp() and throw() must not violate the entry/exit criteria.
14726
0
    CS->getCapturedDecl()->setNothrow();
14727
0
  }
14728
14729
0
  OMPLoopBasedDirective::HelperExprs B;
14730
  // In presence of clause 'collapse' with number of loops, it will
14731
  // define the nested loops number.
14732
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14733
0
      OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
14734
0
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14735
0
      VarsWithImplicitDSA, B);
14736
0
  if (NestedLoopCount == 0)
14737
0
    return StmtError();
14738
14739
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14740
0
         "omp target teams distribute loop exprs were not built");
14741
14742
0
  setFunctionHasBranchProtectedScope();
14743
0
  return OMPTargetTeamsDistributeDirective::Create(
14744
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14745
0
}
14746
14747
StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
14748
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14749
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14750
0
  if (!AStmt)
14751
0
    return StmtError();
14752
14753
0
  auto *CS = cast<CapturedStmt>(AStmt);
14754
  // 1.2.2 OpenMP Language Terminology
14755
  // Structured block - An executable statement with a single entry at the
14756
  // top and a single exit at the bottom.
14757
  // The point of exit cannot be a branch out of the structured block.
14758
  // longjmp() and throw() must not violate the entry/exit criteria.
14759
0
  CS->getCapturedDecl()->setNothrow();
14760
0
  for (int ThisCaptureLevel =
14761
0
           getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
14762
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14763
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14764
    // 1.2.2 OpenMP Language Terminology
14765
    // Structured block - An executable statement with a single entry at the
14766
    // top and a single exit at the bottom.
14767
    // The point of exit cannot be a branch out of the structured block.
14768
    // longjmp() and throw() must not violate the entry/exit criteria.
14769
0
    CS->getCapturedDecl()->setNothrow();
14770
0
  }
14771
14772
0
  OMPLoopBasedDirective::HelperExprs B;
14773
  // In presence of clause 'collapse' with number of loops, it will
14774
  // define the nested loops number.
14775
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14776
0
      OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14777
0
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14778
0
      VarsWithImplicitDSA, B);
14779
0
  if (NestedLoopCount == 0)
14780
0
    return StmtError();
14781
14782
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14783
0
         "omp target teams distribute parallel for loop exprs were not built");
14784
14785
0
  if (!CurContext->isDependentContext()) {
14786
    // Finalize the clauses that need pre-built expressions for CodeGen.
14787
0
    for (OMPClause *C : Clauses) {
14788
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14789
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14790
0
                                     B.NumIterations, *this, CurScope,
14791
0
                                     DSAStack))
14792
0
          return StmtError();
14793
0
    }
14794
0
  }
14795
14796
0
  setFunctionHasBranchProtectedScope();
14797
0
  return OMPTargetTeamsDistributeParallelForDirective::Create(
14798
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14799
0
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14800
0
}
14801
14802
StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
14803
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14804
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14805
0
  if (!AStmt)
14806
0
    return StmtError();
14807
14808
0
  auto *CS = cast<CapturedStmt>(AStmt);
14809
  // 1.2.2 OpenMP Language Terminology
14810
  // Structured block - An executable statement with a single entry at the
14811
  // top and a single exit at the bottom.
14812
  // The point of exit cannot be a branch out of the structured block.
14813
  // longjmp() and throw() must not violate the entry/exit criteria.
14814
0
  CS->getCapturedDecl()->setNothrow();
14815
0
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(
14816
0
           OMPD_target_teams_distribute_parallel_for_simd);
14817
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14818
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14819
    // 1.2.2 OpenMP Language Terminology
14820
    // Structured block - An executable statement with a single entry at the
14821
    // top and a single exit at the bottom.
14822
    // The point of exit cannot be a branch out of the structured block.
14823
    // longjmp() and throw() must not violate the entry/exit criteria.
14824
0
    CS->getCapturedDecl()->setNothrow();
14825
0
  }
14826
14827
0
  OMPLoopBasedDirective::HelperExprs B;
14828
  // In presence of clause 'collapse' with number of loops, it will
14829
  // define the nested loops number.
14830
0
  unsigned NestedLoopCount =
14831
0
      checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
14832
0
                      getCollapseNumberExpr(Clauses),
14833
0
                      nullptr /*ordered not a clause on distribute*/, CS, *this,
14834
0
                      *DSAStack, VarsWithImplicitDSA, B);
14835
0
  if (NestedLoopCount == 0)
14836
0
    return StmtError();
14837
14838
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14839
0
         "omp target teams distribute parallel for simd loop exprs were not "
14840
0
         "built");
14841
14842
0
  if (!CurContext->isDependentContext()) {
14843
    // Finalize the clauses that need pre-built expressions for CodeGen.
14844
0
    for (OMPClause *C : Clauses) {
14845
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14846
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14847
0
                                     B.NumIterations, *this, CurScope,
14848
0
                                     DSAStack))
14849
0
          return StmtError();
14850
0
    }
14851
0
  }
14852
14853
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14854
0
    return StmtError();
14855
14856
0
  setFunctionHasBranchProtectedScope();
14857
0
  return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
14858
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14859
0
}
14860
14861
StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14862
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14863
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14864
0
  if (!AStmt)
14865
0
    return StmtError();
14866
14867
0
  auto *CS = cast<CapturedStmt>(AStmt);
14868
  // 1.2.2 OpenMP Language Terminology
14869
  // Structured block - An executable statement with a single entry at the
14870
  // top and a single exit at the bottom.
14871
  // The point of exit cannot be a branch out of the structured block.
14872
  // longjmp() and throw() must not violate the entry/exit criteria.
14873
0
  CS->getCapturedDecl()->setNothrow();
14874
0
  for (int ThisCaptureLevel =
14875
0
           getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
14876
0
       ThisCaptureLevel > 1; --ThisCaptureLevel) {
14877
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14878
    // 1.2.2 OpenMP Language Terminology
14879
    // Structured block - An executable statement with a single entry at the
14880
    // top and a single exit at the bottom.
14881
    // The point of exit cannot be a branch out of the structured block.
14882
    // longjmp() and throw() must not violate the entry/exit criteria.
14883
0
    CS->getCapturedDecl()->setNothrow();
14884
0
  }
14885
14886
0
  OMPLoopBasedDirective::HelperExprs B;
14887
  // In presence of clause 'collapse' with number of loops, it will
14888
  // define the nested loops number.
14889
0
  unsigned NestedLoopCount = checkOpenMPLoop(
14890
0
      OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14891
0
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14892
0
      VarsWithImplicitDSA, B);
14893
0
  if (NestedLoopCount == 0)
14894
0
    return StmtError();
14895
14896
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14897
0
         "omp target teams distribute simd loop exprs were not built");
14898
14899
0
  if (!CurContext->isDependentContext()) {
14900
    // Finalize the clauses that need pre-built expressions for CodeGen.
14901
0
    for (OMPClause *C : Clauses) {
14902
0
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14903
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14904
0
                                     B.NumIterations, *this, CurScope,
14905
0
                                     DSAStack))
14906
0
          return StmtError();
14907
0
    }
14908
0
  }
14909
14910
0
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14911
0
    return StmtError();
14912
14913
0
  setFunctionHasBranchProtectedScope();
14914
0
  return OMPTargetTeamsDistributeSimdDirective::Create(
14915
0
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14916
0
}
14917
14918
bool Sema::checkTransformableLoopNest(
14919
    OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
14920
    SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14921
    Stmt *&Body,
14922
    SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
14923
0
        &OriginalInits) {
14924
0
  OriginalInits.emplace_back();
14925
0
  bool Result = OMPLoopBasedDirective::doForAllLoops(
14926
0
      AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
14927
0
      [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
14928
0
                                                        Stmt *CurStmt) {
14929
0
        VarsWithInheritedDSAType TmpDSA;
14930
0
        unsigned SingleNumLoops =
14931
0
            checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
14932
0
                            TmpDSA, LoopHelpers[Cnt]);
14933
0
        if (SingleNumLoops == 0)
14934
0
          return true;
14935
0
        assert(SingleNumLoops == 1 && "Expect single loop iteration space");
14936
0
        if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14937
0
          OriginalInits.back().push_back(For->getInit());
14938
0
          Body = For->getBody();
14939
0
        } else {
14940
0
          assert(isa<CXXForRangeStmt>(CurStmt) &&
14941
0
                 "Expected canonical for or range-based for loops.");
14942
0
          auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14943
0
          OriginalInits.back().push_back(CXXFor->getBeginStmt());
14944
0
          Body = CXXFor->getBody();
14945
0
        }
14946
0
        OriginalInits.emplace_back();
14947
0
        return false;
14948
0
      },
14949
0
      [&OriginalInits](OMPLoopBasedDirective *Transform) {
14950
0
        Stmt *DependentPreInits;
14951
0
        if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14952
0
          DependentPreInits = Dir->getPreInits();
14953
0
        else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14954
0
          DependentPreInits = Dir->getPreInits();
14955
0
        else
14956
0
          llvm_unreachable("Unhandled loop transformation");
14957
0
        if (!DependentPreInits)
14958
0
          return;
14959
0
        llvm::append_range(OriginalInits.back(),
14960
0
                           cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14961
0
      });
14962
0
  assert(OriginalInits.back().empty() && "No preinit after innermost loop");
14963
0
  OriginalInits.pop_back();
14964
0
  return Result;
14965
0
}
14966
14967
StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
14968
                                          Stmt *AStmt, SourceLocation StartLoc,
14969
0
                                          SourceLocation EndLoc) {
14970
0
  auto SizesClauses =
14971
0
      OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14972
0
  if (SizesClauses.empty()) {
14973
    // A missing 'sizes' clause is already reported by the parser.
14974
0
    return StmtError();
14975
0
  }
14976
0
  const OMPSizesClause *SizesClause = *SizesClauses.begin();
14977
0
  unsigned NumLoops = SizesClause->getNumSizes();
14978
14979
  // Empty statement should only be possible if there already was an error.
14980
0
  if (!AStmt)
14981
0
    return StmtError();
14982
14983
  // Verify and diagnose loop nest.
14984
0
  SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14985
0
  Stmt *Body = nullptr;
14986
0
  SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
14987
0
      OriginalInits;
14988
0
  if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14989
0
                                  OriginalInits))
14990
0
    return StmtError();
14991
14992
  // Delay tiling to when template is completely instantiated.
14993
0
  if (CurContext->isDependentContext())
14994
0
    return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14995
0
                                    NumLoops, AStmt, nullptr, nullptr);
14996
14997
0
  SmallVector<Decl *, 4> PreInits;
14998
14999
  // Create iteration variables for the generated loops.
15000
0
  SmallVector<VarDecl *, 4> FloorIndVars;
15001
0
  SmallVector<VarDecl *, 4> TileIndVars;
15002
0
  FloorIndVars.resize(NumLoops);
15003
0
  TileIndVars.resize(NumLoops);
15004
0
  for (unsigned I = 0; I < NumLoops; ++I) {
15005
0
    OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
15006
15007
0
    assert(LoopHelper.Counters.size() == 1 &&
15008
0
           "Expect single-dimensional loop iteration space");
15009
0
    auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
15010
0
    std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
15011
0
    DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
15012
0
    QualType CntTy = IterVarRef->getType();
15013
15014
    // Iteration variable for the floor (i.e. outer) loop.
15015
0
    {
15016
0
      std::string FloorCntName =
15017
0
          (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
15018
0
      VarDecl *FloorCntDecl =
15019
0
          buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
15020
0
      FloorIndVars[I] = FloorCntDecl;
15021
0
    }
15022
15023
    // Iteration variable for the tile (i.e. inner) loop.
15024
0
    {
15025
0
      std::string TileCntName =
15026
0
          (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
15027
15028
      // Reuse the iteration variable created by checkOpenMPLoop. It is also
15029
      // used by the expressions to derive the original iteration variable's
15030
      // value from the logical iteration number.
15031
0
      auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
15032
0
      TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
15033
0
      TileIndVars[I] = TileCntDecl;
15034
0
    }
15035
0
    for (auto &P : OriginalInits[I]) {
15036
0
      if (auto *D = P.dyn_cast<Decl *>())
15037
0
        PreInits.push_back(D);
15038
0
      else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
15039
0
        PreInits.append(PI->decl_begin(), PI->decl_end());
15040
0
    }
15041
0
    if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
15042
0
      PreInits.append(PI->decl_begin(), PI->decl_end());
15043
    // Gather declarations for the data members used as counters.
15044
0
    for (Expr *CounterRef : LoopHelper.Counters) {
15045
0
      auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15046
0
      if (isa<OMPCapturedExprDecl>(CounterDecl))
15047
0
        PreInits.push_back(CounterDecl);
15048
0
    }
15049
0
  }
15050
15051
  // Once the original iteration values are set, append the innermost body.
15052
0
  Stmt *Inner = Body;
15053
15054
  // Create tile loops from the inside to the outside.
15055
0
  for (int I = NumLoops - 1; I >= 0; --I) {
15056
0
    OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
15057
0
    Expr *NumIterations = LoopHelper.NumIterations;
15058
0
    auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15059
0
    QualType CntTy = OrigCntVar->getType();
15060
0
    Expr *DimTileSize = SizesClause->getSizesRefs()[I];
15061
0
    Scope *CurScope = getCurScope();
15062
15063
    // Commonly used variables.
15064
0
    DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
15065
0
                                           OrigCntVar->getExprLoc());
15066
0
    DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
15067
0
                                            OrigCntVar->getExprLoc());
15068
15069
    // For init-statement: auto .tile.iv = .floor.iv
15070
0
    AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
15071
0
                         /*DirectInit=*/false);
15072
0
    Decl *CounterDecl = TileIndVars[I];
15073
0
    StmtResult InitStmt = new (Context)
15074
0
        DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
15075
0
                 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15076
0
    if (!InitStmt.isUsable())
15077
0
      return StmtError();
15078
15079
    // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
15080
    // NumIterations)
15081
0
    ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15082
0
                                      BO_Add, FloorIV, DimTileSize);
15083
0
    if (!EndOfTile.isUsable())
15084
0
      return StmtError();
15085
0
    ExprResult IsPartialTile =
15086
0
        BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
15087
0
                   NumIterations, EndOfTile.get());
15088
0
    if (!IsPartialTile.isUsable())
15089
0
      return StmtError();
15090
0
    ExprResult MinTileAndIterSpace = ActOnConditionalOp(
15091
0
        LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
15092
0
        IsPartialTile.get(), NumIterations, EndOfTile.get());
15093
0
    if (!MinTileAndIterSpace.isUsable())
15094
0
      return StmtError();
15095
0
    ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15096
0
                                     BO_LT, TileIV, MinTileAndIterSpace.get());
15097
0
    if (!CondExpr.isUsable())
15098
0
      return StmtError();
15099
15100
    // For incr-statement: ++.tile.iv
15101
0
    ExprResult IncrStmt =
15102
0
        BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
15103
0
    if (!IncrStmt.isUsable())
15104
0
      return StmtError();
15105
15106
    // Statements to set the original iteration variable's value from the
15107
    // logical iteration number.
15108
    // Generated for loop is:
15109
    // Original_for_init;
15110
    // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
15111
    // NumIterations); ++.tile.iv) {
15112
    //   Original_Body;
15113
    //   Original_counter_update;
15114
    // }
15115
    // FIXME: If the innermost body is an loop itself, inserting these
15116
    // statements stops it being recognized  as a perfectly nested loop (e.g.
15117
    // for applying tiling again). If this is the case, sink the expressions
15118
    // further into the inner loop.
15119
0
    SmallVector<Stmt *, 4> BodyParts;
15120
0
    BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15121
0
    BodyParts.push_back(Inner);
15122
0
    Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
15123
0
                                 Inner->getBeginLoc(), Inner->getEndLoc());
15124
0
    Inner = new (Context)
15125
0
        ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
15126
0
                IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
15127
0
                LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15128
0
  }
15129
15130
  // Create floor loops from the inside to the outside.
15131
0
  for (int I = NumLoops - 1; I >= 0; --I) {
15132
0
    auto &LoopHelper = LoopHelpers[I];
15133
0
    Expr *NumIterations = LoopHelper.NumIterations;
15134
0
    DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15135
0
    QualType CntTy = OrigCntVar->getType();
15136
0
    Expr *DimTileSize = SizesClause->getSizesRefs()[I];
15137
0
    Scope *CurScope = getCurScope();
15138
15139
    // Commonly used variables.
15140
0
    DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
15141
0
                                            OrigCntVar->getExprLoc());
15142
15143
    // For init-statement: auto .floor.iv = 0
15144
0
    AddInitializerToDecl(
15145
0
        FloorIndVars[I],
15146
0
        ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15147
0
        /*DirectInit=*/false);
15148
0
    Decl *CounterDecl = FloorIndVars[I];
15149
0
    StmtResult InitStmt = new (Context)
15150
0
        DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
15151
0
                 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15152
0
    if (!InitStmt.isUsable())
15153
0
      return StmtError();
15154
15155
    // For cond-expression: .floor.iv < NumIterations
15156
0
    ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15157
0
                                     BO_LT, FloorIV, NumIterations);
15158
0
    if (!CondExpr.isUsable())
15159
0
      return StmtError();
15160
15161
    // For incr-statement: .floor.iv += DimTileSize
15162
0
    ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
15163
0
                                     BO_AddAssign, FloorIV, DimTileSize);
15164
0
    if (!IncrStmt.isUsable())
15165
0
      return StmtError();
15166
15167
0
    Inner = new (Context)
15168
0
        ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
15169
0
                IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
15170
0
                LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15171
0
  }
15172
15173
0
  return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
15174
0
                                  AStmt, Inner,
15175
0
                                  buildPreInits(Context, PreInits));
15176
0
}
15177
15178
StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
15179
                                            Stmt *AStmt,
15180
                                            SourceLocation StartLoc,
15181
0
                                            SourceLocation EndLoc) {
15182
  // Empty statement should only be possible if there already was an error.
15183
0
  if (!AStmt)
15184
0
    return StmtError();
15185
15186
0
  if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
15187
0
    return StmtError();
15188
15189
0
  const OMPFullClause *FullClause =
15190
0
      OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
15191
0
  const OMPPartialClause *PartialClause =
15192
0
      OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
15193
0
  assert(!(FullClause && PartialClause) &&
15194
0
         "mutual exclusivity must have been checked before");
15195
15196
0
  constexpr unsigned NumLoops = 1;
15197
0
  Stmt *Body = nullptr;
15198
0
  SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
15199
0
      NumLoops);
15200
0
  SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
15201
0
      OriginalInits;
15202
0
  if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
15203
0
                                  Body, OriginalInits))
15204
0
    return StmtError();
15205
15206
0
  unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
15207
15208
  // Delay unrolling to when template is completely instantiated.
15209
0
  if (CurContext->isDependentContext())
15210
0
    return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15211
0
                                      NumGeneratedLoops, nullptr, nullptr);
15212
15213
0
  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
15214
15215
0
  if (FullClause) {
15216
0
    if (!VerifyPositiveIntegerConstantInClause(
15217
0
             LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
15218
0
             /*SuppressExprDiags=*/true)
15219
0
             .isUsable()) {
15220
0
      Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
15221
0
      Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
15222
0
          << "#pragma omp unroll full";
15223
0
      return StmtError();
15224
0
    }
15225
0
  }
15226
15227
  // The generated loop may only be passed to other loop-associated directive
15228
  // when a partial clause is specified. Without the requirement it is
15229
  // sufficient to generate loop unroll metadata at code-generation.
15230
0
  if (NumGeneratedLoops == 0)
15231
0
    return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15232
0
                                      NumGeneratedLoops, nullptr, nullptr);
15233
15234
  // Otherwise, we need to provide a de-sugared/transformed AST that can be
15235
  // associated with another loop directive.
15236
  //
15237
  // The canonical loop analysis return by checkTransformableLoopNest assumes
15238
  // the following structure to be the same loop without transformations or
15239
  // directives applied: \code OriginalInits; LoopHelper.PreInits;
15240
  // LoopHelper.Counters;
15241
  // for (; IV < LoopHelper.NumIterations; ++IV) {
15242
  //   LoopHelper.Updates;
15243
  //   Body;
15244
  // }
15245
  // \endcode
15246
  // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
15247
  // and referenced by LoopHelper.IterationVarRef.
15248
  //
15249
  // The unrolling directive transforms this into the following loop:
15250
  // \code
15251
  // OriginalInits;         \
15252
  // LoopHelper.PreInits;    > NewPreInits
15253
  // LoopHelper.Counters;   /
15254
  // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
15255
  //   #pragma clang loop unroll_count(Factor)
15256
  //   for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
15257
  //   {
15258
  //     LoopHelper.Updates;
15259
  //     Body;
15260
  //   }
15261
  // }
15262
  // \endcode
15263
  // where UIV is a new logical iteration counter. IV must be the same VarDecl
15264
  // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
15265
  // references it. If the partially unrolled loop is associated with another
15266
  // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
15267
  // analyze this loop, i.e. the outer loop must fulfill the constraints of an
15268
  // OpenMP canonical loop. The inner loop is not an associable canonical loop
15269
  // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
15270
  // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
15271
  // property of the OMPLoopBasedDirective instead of statements in
15272
  // CompoundStatement. This is to allow the loop to become a non-outermost loop
15273
  // of a canonical loop nest where these PreInits are emitted before the
15274
  // outermost directive.
15275
15276
  // Determine the PreInit declarations.
15277
0
  SmallVector<Decl *, 4> PreInits;
15278
0
  assert(OriginalInits.size() == 1 &&
15279
0
         "Expecting a single-dimensional loop iteration space");
15280
0
  for (auto &P : OriginalInits[0]) {
15281
0
    if (auto *D = P.dyn_cast<Decl *>())
15282
0
      PreInits.push_back(D);
15283
0
    else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
15284
0
      PreInits.append(PI->decl_begin(), PI->decl_end());
15285
0
  }
15286
0
  if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
15287
0
    PreInits.append(PI->decl_begin(), PI->decl_end());
15288
  // Gather declarations for the data members used as counters.
15289
0
  for (Expr *CounterRef : LoopHelper.Counters) {
15290
0
    auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15291
0
    if (isa<OMPCapturedExprDecl>(CounterDecl))
15292
0
      PreInits.push_back(CounterDecl);
15293
0
  }
15294
15295
0
  auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
15296
0
  QualType IVTy = IterationVarRef->getType();
15297
0
  assert(LoopHelper.Counters.size() == 1 &&
15298
0
         "Expecting a single-dimensional loop iteration space");
15299
0
  auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
15300
15301
  // Determine the unroll factor.
15302
0
  uint64_t Factor;
15303
0
  SourceLocation FactorLoc;
15304
0
  if (Expr *FactorVal = PartialClause->getFactor()) {
15305
0
    Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
15306
0
    FactorLoc = FactorVal->getExprLoc();
15307
0
  } else {
15308
    // TODO: Use a better profitability model.
15309
0
    Factor = 2;
15310
0
  }
15311
0
  assert(Factor > 0 && "Expected positive unroll factor");
15312
0
  auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
15313
0
    return IntegerLiteral::Create(
15314
0
        Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
15315
0
        FactorLoc);
15316
0
  };
15317
15318
  // Iteration variable SourceLocations.
15319
0
  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
15320
0
  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
15321
0
  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
15322
15323
  // Internal variable names.
15324
0
  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
15325
0
  std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
15326
0
  std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
15327
0
  std::string InnerTripCountName =
15328
0
      (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
15329
15330
  // Create the iteration variable for the unrolled loop.
15331
0
  VarDecl *OuterIVDecl =
15332
0
      buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
15333
0
  auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
15334
0
    return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
15335
0
  };
15336
15337
  // Iteration variable for the inner loop: Reuse the iteration variable created
15338
  // by checkOpenMPLoop.
15339
0
  auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15340
0
  InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
15341
0
  auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
15342
0
    return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
15343
0
  };
15344
15345
  // Make a copy of the NumIterations expression for each use: By the AST
15346
  // constraints, every expression object in a DeclContext must be unique.
15347
0
  CaptureVars CopyTransformer(*this);
15348
0
  auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
15349
0
    return AssertSuccess(
15350
0
        CopyTransformer.TransformExpr(LoopHelper.NumIterations));
15351
0
  };
15352
15353
  // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
15354
0
  ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
15355
0
  AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
15356
0
  StmtResult InnerInit = new (Context)
15357
0
      DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15358
0
  if (!InnerInit.isUsable())
15359
0
    return StmtError();
15360
15361
  // Inner For cond-expression:
15362
  // \code
15363
  //   .unroll_inner.iv < .unrolled.iv + Factor &&
15364
  //   .unroll_inner.iv < NumIterations
15365
  // \endcode
15366
  // This conjunction of two conditions allows ScalarEvolution to derive the
15367
  // maximum trip count of the inner loop.
15368
0
  ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15369
0
                                    BO_Add, MakeOuterRef(), MakeFactorExpr());
15370
0
  if (!EndOfTile.isUsable())
15371
0
    return StmtError();
15372
0
  ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15373
0
                                     BO_LT, MakeInnerRef(), EndOfTile.get());
15374
0
  if (!InnerCond1.isUsable())
15375
0
    return StmtError();
15376
0
  ExprResult InnerCond2 =
15377
0
      BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
15378
0
                 MakeNumIterations());
15379
0
  if (!InnerCond2.isUsable())
15380
0
    return StmtError();
15381
0
  ExprResult InnerCond =
15382
0
      BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
15383
0
                 InnerCond1.get(), InnerCond2.get());
15384
0
  if (!InnerCond.isUsable())
15385
0
    return StmtError();
15386
15387
  // Inner For incr-statement: ++.unroll_inner.iv
15388
0
  ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
15389
0
                                      UO_PreInc, MakeInnerRef());
15390
0
  if (!InnerIncr.isUsable())
15391
0
    return StmtError();
15392
15393
  // Inner For statement.
15394
0
  SmallVector<Stmt *> InnerBodyStmts;
15395
0
  InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15396
0
  InnerBodyStmts.push_back(Body);
15397
0
  CompoundStmt *InnerBody =
15398
0
      CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(),
15399
0
                           Body->getBeginLoc(), Body->getEndLoc());
15400
0
  ForStmt *InnerFor = new (Context)
15401
0
      ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
15402
0
              InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
15403
0
              LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15404
15405
  // Unroll metadata for the inner loop.
15406
  // This needs to take into account the remainder portion of the unrolled loop,
15407
  // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
15408
  // supports multiple loop exits. Instead, unroll using a factor equivalent to
15409
  // the maximum trip count, which will also generate a remainder loop. Just
15410
  // `unroll(enable)` (which could have been useful if the user has not
15411
  // specified a concrete factor; even though the outer loop cannot be
15412
  // influenced anymore, would avoid more code bloat than necessary) will refuse
15413
  // the loop because "Won't unroll; remainder loop could not be generated when
15414
  // assuming runtime trip count". Even if it did work, it must not choose a
15415
  // larger unroll factor than the maximum loop length, or it would always just
15416
  // execute the remainder loop.
15417
0
  LoopHintAttr *UnrollHintAttr =
15418
0
      LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
15419
0
                                   LoopHintAttr::Numeric, MakeFactorExpr());
15420
0
  AttributedStmt *InnerUnrolled =
15421
0
      AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
15422
15423
  // Outer For init-statement: auto .unrolled.iv = 0
15424
0
  AddInitializerToDecl(
15425
0
      OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15426
0
      /*DirectInit=*/false);
15427
0
  StmtResult OuterInit = new (Context)
15428
0
      DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15429
0
  if (!OuterInit.isUsable())
15430
0
    return StmtError();
15431
15432
  // Outer For cond-expression: .unrolled.iv < NumIterations
15433
0
  ExprResult OuterConde =
15434
0
      BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
15435
0
                 MakeNumIterations());
15436
0
  if (!OuterConde.isUsable())
15437
0
    return StmtError();
15438
15439
  // Outer For incr-statement: .unrolled.iv += Factor
15440
0
  ExprResult OuterIncr =
15441
0
      BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
15442
0
                 MakeOuterRef(), MakeFactorExpr());
15443
0
  if (!OuterIncr.isUsable())
15444
0
    return StmtError();
15445
15446
  // Outer For statement.
15447
0
  ForStmt *OuterFor = new (Context)
15448
0
      ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
15449
0
              OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
15450
0
              LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15451
15452
0
  return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15453
0
                                    NumGeneratedLoops, OuterFor,
15454
0
                                    buildPreInits(Context, PreInits));
15455
0
}
15456
15457
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
15458
                                             SourceLocation StartLoc,
15459
                                             SourceLocation LParenLoc,
15460
0
                                             SourceLocation EndLoc) {
15461
0
  OMPClause *Res = nullptr;
15462
0
  switch (Kind) {
15463
0
  case OMPC_final:
15464
0
    Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
15465
0
    break;
15466
0
  case OMPC_num_threads:
15467
0
    Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
15468
0
    break;
15469
0
  case OMPC_safelen:
15470
0
    Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
15471
0
    break;
15472
0
  case OMPC_simdlen:
15473
0
    Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
15474
0
    break;
15475
0
  case OMPC_allocator:
15476
0
    Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
15477
0
    break;
15478
0
  case OMPC_collapse:
15479
0
    Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
15480
0
    break;
15481
0
  case OMPC_ordered:
15482
0
    Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
15483
0
    break;
15484
0
  case OMPC_num_teams:
15485
0
    Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
15486
0
    break;
15487
0
  case OMPC_thread_limit:
15488
0
    Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
15489
0
    break;
15490
0
  case OMPC_priority:
15491
0
    Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
15492
0
    break;
15493
0
  case OMPC_hint:
15494
0
    Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
15495
0
    break;
15496
0
  case OMPC_depobj:
15497
0
    Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
15498
0
    break;
15499
0
  case OMPC_detach:
15500
0
    Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
15501
0
    break;
15502
0
  case OMPC_novariants:
15503
0
    Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
15504
0
    break;
15505
0
  case OMPC_nocontext:
15506
0
    Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
15507
0
    break;
15508
0
  case OMPC_filter:
15509
0
    Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
15510
0
    break;
15511
0
  case OMPC_partial:
15512
0
    Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
15513
0
    break;
15514
0
  case OMPC_message:
15515
0
    Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
15516
0
    break;
15517
0
  case OMPC_align:
15518
0
    Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
15519
0
    break;
15520
0
  case OMPC_ompx_dyn_cgroup_mem:
15521
0
    Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc);
15522
0
    break;
15523
0
  case OMPC_grainsize:
15524
0
  case OMPC_num_tasks:
15525
0
  case OMPC_device:
15526
0
  case OMPC_if:
15527
0
  case OMPC_default:
15528
0
  case OMPC_proc_bind:
15529
0
  case OMPC_schedule:
15530
0
  case OMPC_private:
15531
0
  case OMPC_firstprivate:
15532
0
  case OMPC_lastprivate:
15533
0
  case OMPC_shared:
15534
0
  case OMPC_reduction:
15535
0
  case OMPC_task_reduction:
15536
0
  case OMPC_in_reduction:
15537
0
  case OMPC_linear:
15538
0
  case OMPC_aligned:
15539
0
  case OMPC_copyin:
15540
0
  case OMPC_copyprivate:
15541
0
  case OMPC_nowait:
15542
0
  case OMPC_untied:
15543
0
  case OMPC_mergeable:
15544
0
  case OMPC_threadprivate:
15545
0
  case OMPC_sizes:
15546
0
  case OMPC_allocate:
15547
0
  case OMPC_flush:
15548
0
  case OMPC_read:
15549
0
  case OMPC_write:
15550
0
  case OMPC_update:
15551
0
  case OMPC_capture:
15552
0
  case OMPC_compare:
15553
0
  case OMPC_seq_cst:
15554
0
  case OMPC_acq_rel:
15555
0
  case OMPC_acquire:
15556
0
  case OMPC_release:
15557
0
  case OMPC_relaxed:
15558
0
  case OMPC_depend:
15559
0
  case OMPC_threads:
15560
0
  case OMPC_simd:
15561
0
  case OMPC_map:
15562
0
  case OMPC_nogroup:
15563
0
  case OMPC_dist_schedule:
15564
0
  case OMPC_defaultmap:
15565
0
  case OMPC_unknown:
15566
0
  case OMPC_uniform:
15567
0
  case OMPC_to:
15568
0
  case OMPC_from:
15569
0
  case OMPC_use_device_ptr:
15570
0
  case OMPC_use_device_addr:
15571
0
  case OMPC_is_device_ptr:
15572
0
  case OMPC_unified_address:
15573
0
  case OMPC_unified_shared_memory:
15574
0
  case OMPC_reverse_offload:
15575
0
  case OMPC_dynamic_allocators:
15576
0
  case OMPC_atomic_default_mem_order:
15577
0
  case OMPC_device_type:
15578
0
  case OMPC_match:
15579
0
  case OMPC_nontemporal:
15580
0
  case OMPC_order:
15581
0
  case OMPC_at:
15582
0
  case OMPC_severity:
15583
0
  case OMPC_destroy:
15584
0
  case OMPC_inclusive:
15585
0
  case OMPC_exclusive:
15586
0
  case OMPC_uses_allocators:
15587
0
  case OMPC_affinity:
15588
0
  case OMPC_when:
15589
0
  case OMPC_bind:
15590
0
  default:
15591
0
    llvm_unreachable("Clause is not allowed.");
15592
0
  }
15593
0
  return Res;
15594
0
}
15595
15596
// An OpenMP directive such as 'target parallel' has two captured regions:
15597
// for the 'target' and 'parallel' respectively.  This function returns
15598
// the region in which to capture expressions associated with a clause.
15599
// A return value of OMPD_unknown signifies that the expression should not
15600
// be captured.
15601
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
15602
    OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
15603
0
    OpenMPDirectiveKind NameModifier = OMPD_unknown) {
15604
0
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15605
0
  switch (CKind) {
15606
0
  case OMPC_if:
15607
0
    switch (DKind) {
15608
0
    case OMPD_target_parallel_for_simd:
15609
0
      if (OpenMPVersion >= 50 &&
15610
0
          (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15611
0
        CaptureRegion = OMPD_parallel;
15612
0
        break;
15613
0
      }
15614
0
      [[fallthrough]];
15615
0
    case OMPD_target_parallel:
15616
0
    case OMPD_target_parallel_for:
15617
0
    case OMPD_target_parallel_loop:
15618
      // If this clause applies to the nested 'parallel' region, capture within
15619
      // the 'target' region, otherwise do not capture.
15620
0
      if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15621
0
        CaptureRegion = OMPD_target;
15622
0
      break;
15623
0
    case OMPD_target_teams_distribute_parallel_for_simd:
15624
0
      if (OpenMPVersion >= 50 &&
15625
0
          (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15626
0
        CaptureRegion = OMPD_parallel;
15627
0
        break;
15628
0
      }
15629
0
      [[fallthrough]];
15630
0
    case OMPD_target_teams_loop:
15631
0
    case OMPD_target_teams_distribute_parallel_for:
15632
      // If this clause applies to the nested 'parallel' region, capture within
15633
      // the 'teams' region, otherwise do not capture.
15634
0
      if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15635
0
        CaptureRegion = OMPD_teams;
15636
0
      break;
15637
0
    case OMPD_teams_distribute_parallel_for_simd:
15638
0
      if (OpenMPVersion >= 50 &&
15639
0
          (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15640
0
        CaptureRegion = OMPD_parallel;
15641
0
        break;
15642
0
      }
15643
0
      [[fallthrough]];
15644
0
    case OMPD_teams_distribute_parallel_for:
15645
0
      CaptureRegion = OMPD_teams;
15646
0
      break;
15647
0
    case OMPD_target_update:
15648
0
    case OMPD_target_enter_data:
15649
0
    case OMPD_target_exit_data:
15650
0
      CaptureRegion = OMPD_task;
15651
0
      break;
15652
0
    case OMPD_parallel_masked_taskloop:
15653
0
      if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15654
0
        CaptureRegion = OMPD_parallel;
15655
0
      break;
15656
0
    case OMPD_parallel_master_taskloop:
15657
0
      if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15658
0
        CaptureRegion = OMPD_parallel;
15659
0
      break;
15660
0
    case OMPD_parallel_masked_taskloop_simd:
15661
0
      if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15662
0
          NameModifier == OMPD_taskloop) {
15663
0
        CaptureRegion = OMPD_parallel;
15664
0
        break;
15665
0
      }
15666
0
      if (OpenMPVersion <= 45)
15667
0
        break;
15668
0
      if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15669
0
        CaptureRegion = OMPD_taskloop;
15670
0
      break;
15671
0
    case OMPD_parallel_master_taskloop_simd:
15672
0
      if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15673
0
          NameModifier == OMPD_taskloop) {
15674
0
        CaptureRegion = OMPD_parallel;
15675
0
        break;
15676
0
      }
15677
0
      if (OpenMPVersion <= 45)
15678
0
        break;
15679
0
      if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15680
0
        CaptureRegion = OMPD_taskloop;
15681
0
      break;
15682
0
    case OMPD_parallel_for_simd:
15683
0
      if (OpenMPVersion <= 45)
15684
0
        break;
15685
0
      if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15686
0
        CaptureRegion = OMPD_parallel;
15687
0
      break;
15688
0
    case OMPD_taskloop_simd:
15689
0
    case OMPD_master_taskloop_simd:
15690
0
    case OMPD_masked_taskloop_simd:
15691
0
      if (OpenMPVersion <= 45)
15692
0
        break;
15693
0
      if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15694
0
        CaptureRegion = OMPD_taskloop;
15695
0
      break;
15696
0
    case OMPD_distribute_parallel_for_simd:
15697
0
      if (OpenMPVersion <= 45)
15698
0
        break;
15699
0
      if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15700
0
        CaptureRegion = OMPD_parallel;
15701
0
      break;
15702
0
    case OMPD_target_simd:
15703
0
      if (OpenMPVersion >= 50 &&
15704
0
          (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15705
0
        CaptureRegion = OMPD_target;
15706
0
      break;
15707
0
    case OMPD_teams_distribute_simd:
15708
0
    case OMPD_target_teams_distribute_simd:
15709
0
      if (OpenMPVersion >= 50 &&
15710
0
          (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15711
0
        CaptureRegion = OMPD_teams;
15712
0
      break;
15713
0
    case OMPD_cancel:
15714
0
    case OMPD_parallel:
15715
0
    case OMPD_parallel_master:
15716
0
    case OMPD_parallel_masked:
15717
0
    case OMPD_parallel_sections:
15718
0
    case OMPD_parallel_for:
15719
0
    case OMPD_parallel_loop:
15720
0
    case OMPD_target:
15721
0
    case OMPD_target_teams:
15722
0
    case OMPD_target_teams_distribute:
15723
0
    case OMPD_distribute_parallel_for:
15724
0
    case OMPD_task:
15725
0
    case OMPD_taskloop:
15726
0
    case OMPD_master_taskloop:
15727
0
    case OMPD_masked_taskloop:
15728
0
    case OMPD_target_data:
15729
0
    case OMPD_simd:
15730
0
    case OMPD_for_simd:
15731
0
    case OMPD_distribute_simd:
15732
      // Do not capture if-clause expressions.
15733
0
      break;
15734
0
    case OMPD_threadprivate:
15735
0
    case OMPD_allocate:
15736
0
    case OMPD_taskyield:
15737
0
    case OMPD_error:
15738
0
    case OMPD_barrier:
15739
0
    case OMPD_taskwait:
15740
0
    case OMPD_cancellation_point:
15741
0
    case OMPD_flush:
15742
0
    case OMPD_depobj:
15743
0
    case OMPD_scan:
15744
0
    case OMPD_declare_reduction:
15745
0
    case OMPD_declare_mapper:
15746
0
    case OMPD_declare_simd:
15747
0
    case OMPD_declare_variant:
15748
0
    case OMPD_begin_declare_variant:
15749
0
    case OMPD_end_declare_variant:
15750
0
    case OMPD_declare_target:
15751
0
    case OMPD_end_declare_target:
15752
0
    case OMPD_loop:
15753
0
    case OMPD_teams_loop:
15754
0
    case OMPD_teams:
15755
0
    case OMPD_tile:
15756
0
    case OMPD_unroll:
15757
0
    case OMPD_for:
15758
0
    case OMPD_sections:
15759
0
    case OMPD_section:
15760
0
    case OMPD_single:
15761
0
    case OMPD_master:
15762
0
    case OMPD_masked:
15763
0
    case OMPD_critical:
15764
0
    case OMPD_taskgroup:
15765
0
    case OMPD_distribute:
15766
0
    case OMPD_ordered:
15767
0
    case OMPD_atomic:
15768
0
    case OMPD_teams_distribute:
15769
0
    case OMPD_requires:
15770
0
    case OMPD_metadirective:
15771
0
      llvm_unreachable("Unexpected OpenMP directive with if-clause");
15772
0
    case OMPD_unknown:
15773
0
    default:
15774
0
      llvm_unreachable("Unknown OpenMP directive");
15775
0
    }
15776
0
    break;
15777
0
  case OMPC_num_threads:
15778
0
    switch (DKind) {
15779
0
    case OMPD_target_parallel:
15780
0
    case OMPD_target_parallel_for:
15781
0
    case OMPD_target_parallel_for_simd:
15782
0
    case OMPD_target_parallel_loop:
15783
0
      CaptureRegion = OMPD_target;
15784
0
      break;
15785
0
    case OMPD_teams_distribute_parallel_for:
15786
0
    case OMPD_teams_distribute_parallel_for_simd:
15787
0
    case OMPD_target_teams_distribute_parallel_for:
15788
0
    case OMPD_target_teams_distribute_parallel_for_simd:
15789
0
      CaptureRegion = OMPD_teams;
15790
0
      break;
15791
0
    case OMPD_parallel:
15792
0
    case OMPD_parallel_master:
15793
0
    case OMPD_parallel_masked:
15794
0
    case OMPD_parallel_sections:
15795
0
    case OMPD_parallel_for:
15796
0
    case OMPD_parallel_for_simd:
15797
0
    case OMPD_parallel_loop:
15798
0
    case OMPD_distribute_parallel_for:
15799
0
    case OMPD_distribute_parallel_for_simd:
15800
0
    case OMPD_parallel_master_taskloop:
15801
0
    case OMPD_parallel_masked_taskloop:
15802
0
    case OMPD_parallel_master_taskloop_simd:
15803
0
    case OMPD_parallel_masked_taskloop_simd:
15804
      // Do not capture num_threads-clause expressions.
15805
0
      break;
15806
0
    case OMPD_target_data:
15807
0
    case OMPD_target_enter_data:
15808
0
    case OMPD_target_exit_data:
15809
0
    case OMPD_target_update:
15810
0
    case OMPD_target:
15811
0
    case OMPD_target_simd:
15812
0
    case OMPD_target_teams:
15813
0
    case OMPD_target_teams_distribute:
15814
0
    case OMPD_target_teams_distribute_simd:
15815
0
    case OMPD_cancel:
15816
0
    case OMPD_task:
15817
0
    case OMPD_taskloop:
15818
0
    case OMPD_taskloop_simd:
15819
0
    case OMPD_master_taskloop:
15820
0
    case OMPD_masked_taskloop:
15821
0
    case OMPD_master_taskloop_simd:
15822
0
    case OMPD_masked_taskloop_simd:
15823
0
    case OMPD_threadprivate:
15824
0
    case OMPD_allocate:
15825
0
    case OMPD_taskyield:
15826
0
    case OMPD_error:
15827
0
    case OMPD_barrier:
15828
0
    case OMPD_taskwait:
15829
0
    case OMPD_cancellation_point:
15830
0
    case OMPD_flush:
15831
0
    case OMPD_depobj:
15832
0
    case OMPD_scan:
15833
0
    case OMPD_declare_reduction:
15834
0
    case OMPD_declare_mapper:
15835
0
    case OMPD_declare_simd:
15836
0
    case OMPD_declare_variant:
15837
0
    case OMPD_begin_declare_variant:
15838
0
    case OMPD_end_declare_variant:
15839
0
    case OMPD_declare_target:
15840
0
    case OMPD_end_declare_target:
15841
0
    case OMPD_loop:
15842
0
    case OMPD_teams_loop:
15843
0
    case OMPD_target_teams_loop:
15844
0
    case OMPD_teams:
15845
0
    case OMPD_simd:
15846
0
    case OMPD_tile:
15847
0
    case OMPD_unroll:
15848
0
    case OMPD_for:
15849
0
    case OMPD_for_simd:
15850
0
    case OMPD_sections:
15851
0
    case OMPD_section:
15852
0
    case OMPD_single:
15853
0
    case OMPD_master:
15854
0
    case OMPD_masked:
15855
0
    case OMPD_critical:
15856
0
    case OMPD_taskgroup:
15857
0
    case OMPD_distribute:
15858
0
    case OMPD_ordered:
15859
0
    case OMPD_atomic:
15860
0
    case OMPD_distribute_simd:
15861
0
    case OMPD_teams_distribute:
15862
0
    case OMPD_teams_distribute_simd:
15863
0
    case OMPD_requires:
15864
0
    case OMPD_metadirective:
15865
0
      llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
15866
0
    case OMPD_unknown:
15867
0
    default:
15868
0
      llvm_unreachable("Unknown OpenMP directive");
15869
0
    }
15870
0
    break;
15871
0
  case OMPC_num_teams:
15872
0
    switch (DKind) {
15873
0
    case OMPD_target_teams:
15874
0
    case OMPD_target_teams_distribute:
15875
0
    case OMPD_target_teams_distribute_simd:
15876
0
    case OMPD_target_teams_distribute_parallel_for:
15877
0
    case OMPD_target_teams_distribute_parallel_for_simd:
15878
0
    case OMPD_target_teams_loop:
15879
0
      CaptureRegion = OMPD_target;
15880
0
      break;
15881
0
    case OMPD_teams_distribute_parallel_for:
15882
0
    case OMPD_teams_distribute_parallel_for_simd:
15883
0
    case OMPD_teams:
15884
0
    case OMPD_teams_distribute:
15885
0
    case OMPD_teams_distribute_simd:
15886
0
    case OMPD_teams_loop:
15887
      // Do not capture num_teams-clause expressions.
15888
0
      break;
15889
0
    case OMPD_distribute_parallel_for:
15890
0
    case OMPD_distribute_parallel_for_simd:
15891
0
    case OMPD_task:
15892
0
    case OMPD_taskloop:
15893
0
    case OMPD_taskloop_simd:
15894
0
    case OMPD_master_taskloop:
15895
0
    case OMPD_masked_taskloop:
15896
0
    case OMPD_master_taskloop_simd:
15897
0
    case OMPD_masked_taskloop_simd:
15898
0
    case OMPD_parallel_master_taskloop:
15899
0
    case OMPD_parallel_masked_taskloop:
15900
0
    case OMPD_parallel_master_taskloop_simd:
15901
0
    case OMPD_parallel_masked_taskloop_simd:
15902
0
    case OMPD_target_data:
15903
0
    case OMPD_target_enter_data:
15904
0
    case OMPD_target_exit_data:
15905
0
    case OMPD_target_update:
15906
0
    case OMPD_cancel:
15907
0
    case OMPD_parallel:
15908
0
    case OMPD_parallel_master:
15909
0
    case OMPD_parallel_masked:
15910
0
    case OMPD_parallel_sections:
15911
0
    case OMPD_parallel_for:
15912
0
    case OMPD_parallel_for_simd:
15913
0
    case OMPD_parallel_loop:
15914
0
    case OMPD_target:
15915
0
    case OMPD_target_simd:
15916
0
    case OMPD_target_parallel:
15917
0
    case OMPD_target_parallel_for:
15918
0
    case OMPD_target_parallel_for_simd:
15919
0
    case OMPD_target_parallel_loop:
15920
0
    case OMPD_threadprivate:
15921
0
    case OMPD_allocate:
15922
0
    case OMPD_taskyield:
15923
0
    case OMPD_error:
15924
0
    case OMPD_barrier:
15925
0
    case OMPD_taskwait:
15926
0
    case OMPD_cancellation_point:
15927
0
    case OMPD_flush:
15928
0
    case OMPD_depobj:
15929
0
    case OMPD_scan:
15930
0
    case OMPD_declare_reduction:
15931
0
    case OMPD_declare_mapper:
15932
0
    case OMPD_declare_simd:
15933
0
    case OMPD_declare_variant:
15934
0
    case OMPD_begin_declare_variant:
15935
0
    case OMPD_end_declare_variant:
15936
0
    case OMPD_declare_target:
15937
0
    case OMPD_end_declare_target:
15938
0
    case OMPD_loop:
15939
0
    case OMPD_simd:
15940
0
    case OMPD_tile:
15941
0
    case OMPD_unroll:
15942
0
    case OMPD_for:
15943
0
    case OMPD_for_simd:
15944
0
    case OMPD_sections:
15945
0
    case OMPD_section:
15946
0
    case OMPD_single:
15947
0
    case OMPD_master:
15948
0
    case OMPD_masked:
15949
0
    case OMPD_critical:
15950
0
    case OMPD_taskgroup:
15951
0
    case OMPD_distribute:
15952
0
    case OMPD_ordered:
15953
0
    case OMPD_atomic:
15954
0
    case OMPD_distribute_simd:
15955
0
    case OMPD_requires:
15956
0
    case OMPD_metadirective:
15957
0
      llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
15958
0
    case OMPD_unknown:
15959
0
    default:
15960
0
      llvm_unreachable("Unknown OpenMP directive");
15961
0
    }
15962
0
    break;
15963
0
  case OMPC_thread_limit:
15964
0
    switch (DKind) {
15965
0
    case OMPD_target:
15966
0
    case OMPD_target_teams:
15967
0
    case OMPD_target_teams_distribute:
15968
0
    case OMPD_target_teams_distribute_simd:
15969
0
    case OMPD_target_teams_distribute_parallel_for:
15970
0
    case OMPD_target_teams_distribute_parallel_for_simd:
15971
0
    case OMPD_target_teams_loop:
15972
0
    case OMPD_target_simd:
15973
0
    case OMPD_target_parallel:
15974
0
    case OMPD_target_parallel_for:
15975
0
    case OMPD_target_parallel_for_simd:
15976
0
    case OMPD_target_parallel_loop:
15977
0
      CaptureRegion = OMPD_target;
15978
0
      break;
15979
0
    case OMPD_teams_distribute_parallel_for:
15980
0
    case OMPD_teams_distribute_parallel_for_simd:
15981
0
    case OMPD_teams:
15982
0
    case OMPD_teams_distribute:
15983
0
    case OMPD_teams_distribute_simd:
15984
0
    case OMPD_teams_loop:
15985
      // Do not capture thread_limit-clause expressions.
15986
0
      break;
15987
0
    case OMPD_distribute_parallel_for:
15988
0
    case OMPD_distribute_parallel_for_simd:
15989
0
    case OMPD_task:
15990
0
    case OMPD_taskloop:
15991
0
    case OMPD_taskloop_simd:
15992
0
    case OMPD_master_taskloop:
15993
0
    case OMPD_masked_taskloop:
15994
0
    case OMPD_master_taskloop_simd:
15995
0
    case OMPD_masked_taskloop_simd:
15996
0
    case OMPD_parallel_master_taskloop:
15997
0
    case OMPD_parallel_masked_taskloop:
15998
0
    case OMPD_parallel_master_taskloop_simd:
15999
0
    case OMPD_parallel_masked_taskloop_simd:
16000
0
    case OMPD_target_data:
16001
0
    case OMPD_target_enter_data:
16002
0
    case OMPD_target_exit_data:
16003
0
    case OMPD_target_update:
16004
0
    case OMPD_cancel:
16005
0
    case OMPD_parallel:
16006
0
    case OMPD_parallel_master:
16007
0
    case OMPD_parallel_masked:
16008
0
    case OMPD_parallel_sections:
16009
0
    case OMPD_parallel_for:
16010
0
    case OMPD_parallel_for_simd:
16011
0
    case OMPD_parallel_loop:
16012
0
    case OMPD_threadprivate:
16013
0
    case OMPD_allocate:
16014
0
    case OMPD_taskyield:
16015
0
    case OMPD_error:
16016
0
    case OMPD_barrier:
16017
0
    case OMPD_taskwait:
16018
0
    case OMPD_cancellation_point:
16019
0
    case OMPD_flush:
16020
0
    case OMPD_depobj:
16021
0
    case OMPD_scan:
16022
0
    case OMPD_declare_reduction:
16023
0
    case OMPD_declare_mapper:
16024
0
    case OMPD_declare_simd:
16025
0
    case OMPD_declare_variant:
16026
0
    case OMPD_begin_declare_variant:
16027
0
    case OMPD_end_declare_variant:
16028
0
    case OMPD_declare_target:
16029
0
    case OMPD_end_declare_target:
16030
0
    case OMPD_loop:
16031
0
    case OMPD_simd:
16032
0
    case OMPD_tile:
16033
0
    case OMPD_unroll:
16034
0
    case OMPD_for:
16035
0
    case OMPD_for_simd:
16036
0
    case OMPD_sections:
16037
0
    case OMPD_section:
16038
0
    case OMPD_single:
16039
0
    case OMPD_master:
16040
0
    case OMPD_masked:
16041
0
    case OMPD_critical:
16042
0
    case OMPD_taskgroup:
16043
0
    case OMPD_distribute:
16044
0
    case OMPD_ordered:
16045
0
    case OMPD_atomic:
16046
0
    case OMPD_distribute_simd:
16047
0
    case OMPD_requires:
16048
0
    case OMPD_metadirective:
16049
0
      llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
16050
0
    case OMPD_unknown:
16051
0
    default:
16052
0
      llvm_unreachable("Unknown OpenMP directive");
16053
0
    }
16054
0
    break;
16055
0
  case OMPC_schedule:
16056
0
    switch (DKind) {
16057
0
    case OMPD_parallel_for:
16058
0
    case OMPD_parallel_for_simd:
16059
0
    case OMPD_distribute_parallel_for:
16060
0
    case OMPD_distribute_parallel_for_simd:
16061
0
    case OMPD_teams_distribute_parallel_for:
16062
0
    case OMPD_teams_distribute_parallel_for_simd:
16063
0
    case OMPD_target_parallel_for:
16064
0
    case OMPD_target_parallel_for_simd:
16065
0
    case OMPD_target_teams_distribute_parallel_for:
16066
0
    case OMPD_target_teams_distribute_parallel_for_simd:
16067
0
      CaptureRegion = OMPD_parallel;
16068
0
      break;
16069
0
    case OMPD_for:
16070
0
    case OMPD_for_simd:
16071
      // Do not capture schedule-clause expressions.
16072
0
      break;
16073
0
    case OMPD_task:
16074
0
    case OMPD_taskloop:
16075
0
    case OMPD_taskloop_simd:
16076
0
    case OMPD_master_taskloop:
16077
0
    case OMPD_masked_taskloop:
16078
0
    case OMPD_master_taskloop_simd:
16079
0
    case OMPD_masked_taskloop_simd:
16080
0
    case OMPD_parallel_master_taskloop:
16081
0
    case OMPD_parallel_masked_taskloop:
16082
0
    case OMPD_parallel_master_taskloop_simd:
16083
0
    case OMPD_parallel_masked_taskloop_simd:
16084
0
    case OMPD_target_data:
16085
0
    case OMPD_target_enter_data:
16086
0
    case OMPD_target_exit_data:
16087
0
    case OMPD_target_update:
16088
0
    case OMPD_teams:
16089
0
    case OMPD_teams_distribute:
16090
0
    case OMPD_teams_distribute_simd:
16091
0
    case OMPD_target_teams_distribute:
16092
0
    case OMPD_target_teams_distribute_simd:
16093
0
    case OMPD_target:
16094
0
    case OMPD_target_simd:
16095
0
    case OMPD_target_parallel:
16096
0
    case OMPD_cancel:
16097
0
    case OMPD_parallel:
16098
0
    case OMPD_parallel_master:
16099
0
    case OMPD_parallel_masked:
16100
0
    case OMPD_parallel_sections:
16101
0
    case OMPD_threadprivate:
16102
0
    case OMPD_allocate:
16103
0
    case OMPD_taskyield:
16104
0
    case OMPD_error:
16105
0
    case OMPD_barrier:
16106
0
    case OMPD_taskwait:
16107
0
    case OMPD_cancellation_point:
16108
0
    case OMPD_flush:
16109
0
    case OMPD_depobj:
16110
0
    case OMPD_scan:
16111
0
    case OMPD_declare_reduction:
16112
0
    case OMPD_declare_mapper:
16113
0
    case OMPD_declare_simd:
16114
0
    case OMPD_declare_variant:
16115
0
    case OMPD_begin_declare_variant:
16116
0
    case OMPD_end_declare_variant:
16117
0
    case OMPD_declare_target:
16118
0
    case OMPD_end_declare_target:
16119
0
    case OMPD_loop:
16120
0
    case OMPD_teams_loop:
16121
0
    case OMPD_target_teams_loop:
16122
0
    case OMPD_parallel_loop:
16123
0
    case OMPD_target_parallel_loop:
16124
0
    case OMPD_simd:
16125
0
    case OMPD_tile:
16126
0
    case OMPD_unroll:
16127
0
    case OMPD_sections:
16128
0
    case OMPD_section:
16129
0
    case OMPD_single:
16130
0
    case OMPD_master:
16131
0
    case OMPD_masked:
16132
0
    case OMPD_critical:
16133
0
    case OMPD_taskgroup:
16134
0
    case OMPD_distribute:
16135
0
    case OMPD_ordered:
16136
0
    case OMPD_atomic:
16137
0
    case OMPD_distribute_simd:
16138
0
    case OMPD_target_teams:
16139
0
    case OMPD_requires:
16140
0
    case OMPD_metadirective:
16141
0
      llvm_unreachable("Unexpected OpenMP directive with schedule clause");
16142
0
    case OMPD_unknown:
16143
0
    default:
16144
0
      llvm_unreachable("Unknown OpenMP directive");
16145
0
    }
16146
0
    break;
16147
0
  case OMPC_dist_schedule:
16148
0
    switch (DKind) {
16149
0
    case OMPD_teams_distribute_parallel_for:
16150
0
    case OMPD_teams_distribute_parallel_for_simd:
16151
0
    case OMPD_teams_distribute:
16152
0
    case OMPD_teams_distribute_simd:
16153
0
    case OMPD_target_teams_distribute_parallel_for:
16154
0
    case OMPD_target_teams_distribute_parallel_for_simd:
16155
0
    case OMPD_target_teams_distribute:
16156
0
    case OMPD_target_teams_distribute_simd:
16157
0
      CaptureRegion = OMPD_teams;
16158
0
      break;
16159
0
    case OMPD_distribute_parallel_for:
16160
0
    case OMPD_distribute_parallel_for_simd:
16161
0
    case OMPD_distribute:
16162
0
    case OMPD_distribute_simd:
16163
      // Do not capture dist_schedule-clause expressions.
16164
0
      break;
16165
0
    case OMPD_parallel_for:
16166
0
    case OMPD_parallel_for_simd:
16167
0
    case OMPD_target_parallel_for_simd:
16168
0
    case OMPD_target_parallel_for:
16169
0
    case OMPD_task:
16170
0
    case OMPD_taskloop:
16171
0
    case OMPD_taskloop_simd:
16172
0
    case OMPD_master_taskloop:
16173
0
    case OMPD_masked_taskloop:
16174
0
    case OMPD_master_taskloop_simd:
16175
0
    case OMPD_masked_taskloop_simd:
16176
0
    case OMPD_parallel_master_taskloop:
16177
0
    case OMPD_parallel_masked_taskloop:
16178
0
    case OMPD_parallel_master_taskloop_simd:
16179
0
    case OMPD_parallel_masked_taskloop_simd:
16180
0
    case OMPD_target_data:
16181
0
    case OMPD_target_enter_data:
16182
0
    case OMPD_target_exit_data:
16183
0
    case OMPD_target_update:
16184
0
    case OMPD_teams:
16185
0
    case OMPD_target:
16186
0
    case OMPD_target_simd:
16187
0
    case OMPD_target_parallel:
16188
0
    case OMPD_cancel:
16189
0
    case OMPD_parallel:
16190
0
    case OMPD_parallel_master:
16191
0
    case OMPD_parallel_masked:
16192
0
    case OMPD_parallel_sections:
16193
0
    case OMPD_threadprivate:
16194
0
    case OMPD_allocate:
16195
0
    case OMPD_taskyield:
16196
0
    case OMPD_error:
16197
0
    case OMPD_barrier:
16198
0
    case OMPD_taskwait:
16199
0
    case OMPD_cancellation_point:
16200
0
    case OMPD_flush:
16201
0
    case OMPD_depobj:
16202
0
    case OMPD_scan:
16203
0
    case OMPD_declare_reduction:
16204
0
    case OMPD_declare_mapper:
16205
0
    case OMPD_declare_simd:
16206
0
    case OMPD_declare_variant:
16207
0
    case OMPD_begin_declare_variant:
16208
0
    case OMPD_end_declare_variant:
16209
0
    case OMPD_declare_target:
16210
0
    case OMPD_end_declare_target:
16211
0
    case OMPD_loop:
16212
0
    case OMPD_teams_loop:
16213
0
    case OMPD_target_teams_loop:
16214
0
    case OMPD_parallel_loop:
16215
0
    case OMPD_target_parallel_loop:
16216
0
    case OMPD_simd:
16217
0
    case OMPD_tile:
16218
0
    case OMPD_unroll:
16219
0
    case OMPD_for:
16220
0
    case OMPD_for_simd:
16221
0
    case OMPD_sections:
16222
0
    case OMPD_section:
16223
0
    case OMPD_single:
16224
0
    case OMPD_master:
16225
0
    case OMPD_masked:
16226
0
    case OMPD_critical:
16227
0
    case OMPD_taskgroup:
16228
0
    case OMPD_ordered:
16229
0
    case OMPD_atomic:
16230
0
    case OMPD_target_teams:
16231
0
    case OMPD_requires:
16232
0
    case OMPD_metadirective:
16233
0
      llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
16234
0
    case OMPD_unknown:
16235
0
    default:
16236
0
      llvm_unreachable("Unknown OpenMP directive");
16237
0
    }
16238
0
    break;
16239
0
  case OMPC_ompx_dyn_cgroup_mem:
16240
0
    switch (DKind) {
16241
0
    case OMPD_target:
16242
0
    case OMPD_target_simd:
16243
0
    case OMPD_target_teams:
16244
0
    case OMPD_target_parallel:
16245
0
    case OMPD_target_teams_distribute:
16246
0
    case OMPD_target_teams_distribute_simd:
16247
0
    case OMPD_target_parallel_for:
16248
0
    case OMPD_target_parallel_for_simd:
16249
0
    case OMPD_target_parallel_loop:
16250
0
    case OMPD_target_teams_distribute_parallel_for:
16251
0
    case OMPD_target_teams_distribute_parallel_for_simd:
16252
0
    case OMPD_target_teams_loop:
16253
0
      CaptureRegion = OMPD_target;
16254
0
      break;
16255
0
    default:
16256
0
      llvm_unreachable("Unknown OpenMP directive");
16257
0
    }
16258
0
    break;
16259
0
  case OMPC_device:
16260
0
    switch (DKind) {
16261
0
    case OMPD_target_update:
16262
0
    case OMPD_target_enter_data:
16263
0
    case OMPD_target_exit_data:
16264
0
    case OMPD_target:
16265
0
    case OMPD_target_simd:
16266
0
    case OMPD_target_teams:
16267
0
    case OMPD_target_parallel:
16268
0
    case OMPD_target_teams_distribute:
16269
0
    case OMPD_target_teams_distribute_simd:
16270
0
    case OMPD_target_parallel_for:
16271
0
    case OMPD_target_parallel_for_simd:
16272
0
    case OMPD_target_parallel_loop:
16273
0
    case OMPD_target_teams_distribute_parallel_for:
16274
0
    case OMPD_target_teams_distribute_parallel_for_simd:
16275
0
    case OMPD_target_teams_loop:
16276
0
    case OMPD_dispatch:
16277
0
      CaptureRegion = OMPD_task;
16278
0
      break;
16279
0
    case OMPD_target_data:
16280
0
    case OMPD_interop:
16281
      // Do not capture device-clause expressions.
16282
0
      break;
16283
0
    case OMPD_teams_distribute_parallel_for:
16284
0
    case OMPD_teams_distribute_parallel_for_simd:
16285
0
    case OMPD_teams:
16286
0
    case OMPD_teams_distribute:
16287
0
    case OMPD_teams_distribute_simd:
16288
0
    case OMPD_distribute_parallel_for:
16289
0
    case OMPD_distribute_parallel_for_simd:
16290
0
    case OMPD_task:
16291
0
    case OMPD_taskloop:
16292
0
    case OMPD_taskloop_simd:
16293
0
    case OMPD_master_taskloop:
16294
0
    case OMPD_masked_taskloop:
16295
0
    case OMPD_master_taskloop_simd:
16296
0
    case OMPD_masked_taskloop_simd:
16297
0
    case OMPD_parallel_master_taskloop:
16298
0
    case OMPD_parallel_masked_taskloop:
16299
0
    case OMPD_parallel_master_taskloop_simd:
16300
0
    case OMPD_parallel_masked_taskloop_simd:
16301
0
    case OMPD_cancel:
16302
0
    case OMPD_parallel:
16303
0
    case OMPD_parallel_master:
16304
0
    case OMPD_parallel_masked:
16305
0
    case OMPD_parallel_sections:
16306
0
    case OMPD_parallel_for:
16307
0
    case OMPD_parallel_for_simd:
16308
0
    case OMPD_threadprivate:
16309
0
    case OMPD_allocate:
16310
0
    case OMPD_taskyield:
16311
0
    case OMPD_error:
16312
0
    case OMPD_barrier:
16313
0
    case OMPD_taskwait:
16314
0
    case OMPD_cancellation_point:
16315
0
    case OMPD_flush:
16316
0
    case OMPD_depobj:
16317
0
    case OMPD_scan:
16318
0
    case OMPD_declare_reduction:
16319
0
    case OMPD_declare_mapper:
16320
0
    case OMPD_declare_simd:
16321
0
    case OMPD_declare_variant:
16322
0
    case OMPD_begin_declare_variant:
16323
0
    case OMPD_end_declare_variant:
16324
0
    case OMPD_declare_target:
16325
0
    case OMPD_end_declare_target:
16326
0
    case OMPD_loop:
16327
0
    case OMPD_teams_loop:
16328
0
    case OMPD_parallel_loop:
16329
0
    case OMPD_simd:
16330
0
    case OMPD_tile:
16331
0
    case OMPD_unroll:
16332
0
    case OMPD_for:
16333
0
    case OMPD_for_simd:
16334
0
    case OMPD_sections:
16335
0
    case OMPD_section:
16336
0
    case OMPD_single:
16337
0
    case OMPD_master:
16338
0
    case OMPD_masked:
16339
0
    case OMPD_critical:
16340
0
    case OMPD_taskgroup:
16341
0
    case OMPD_distribute:
16342
0
    case OMPD_ordered:
16343
0
    case OMPD_atomic:
16344
0
    case OMPD_distribute_simd:
16345
0
    case OMPD_requires:
16346
0
    case OMPD_metadirective:
16347
0
      llvm_unreachable("Unexpected OpenMP directive with device-clause");
16348
0
    case OMPD_unknown:
16349
0
    default:
16350
0
      llvm_unreachable("Unknown OpenMP directive");
16351
0
    }
16352
0
    break;
16353
0
  case OMPC_grainsize:
16354
0
  case OMPC_num_tasks:
16355
0
  case OMPC_final:
16356
0
  case OMPC_priority:
16357
0
    switch (DKind) {
16358
0
    case OMPD_task:
16359
0
    case OMPD_taskloop:
16360
0
    case OMPD_taskloop_simd:
16361
0
    case OMPD_master_taskloop:
16362
0
    case OMPD_masked_taskloop:
16363
0
    case OMPD_master_taskloop_simd:
16364
0
    case OMPD_masked_taskloop_simd:
16365
0
      break;
16366
0
    case OMPD_parallel_masked_taskloop:
16367
0
    case OMPD_parallel_masked_taskloop_simd:
16368
0
    case OMPD_parallel_master_taskloop:
16369
0
    case OMPD_parallel_master_taskloop_simd:
16370
0
      CaptureRegion = OMPD_parallel;
16371
0
      break;
16372
0
    case OMPD_target_update:
16373
0
    case OMPD_target_enter_data:
16374
0
    case OMPD_target_exit_data:
16375
0
    case OMPD_target:
16376
0
    case OMPD_target_simd:
16377
0
    case OMPD_target_teams:
16378
0
    case OMPD_target_parallel:
16379
0
    case OMPD_target_teams_distribute:
16380
0
    case OMPD_target_teams_distribute_simd:
16381
0
    case OMPD_target_parallel_for:
16382
0
    case OMPD_target_parallel_for_simd:
16383
0
    case OMPD_target_teams_distribute_parallel_for:
16384
0
    case OMPD_target_teams_distribute_parallel_for_simd:
16385
0
    case OMPD_target_data:
16386
0
    case OMPD_teams_distribute_parallel_for:
16387
0
    case OMPD_teams_distribute_parallel_for_simd:
16388
0
    case OMPD_teams:
16389
0
    case OMPD_teams_distribute:
16390
0
    case OMPD_teams_distribute_simd:
16391
0
    case OMPD_distribute_parallel_for:
16392
0
    case OMPD_distribute_parallel_for_simd:
16393
0
    case OMPD_cancel:
16394
0
    case OMPD_parallel:
16395
0
    case OMPD_parallel_master:
16396
0
    case OMPD_parallel_masked:
16397
0
    case OMPD_parallel_sections:
16398
0
    case OMPD_parallel_for:
16399
0
    case OMPD_parallel_for_simd:
16400
0
    case OMPD_threadprivate:
16401
0
    case OMPD_allocate:
16402
0
    case OMPD_taskyield:
16403
0
    case OMPD_error:
16404
0
    case OMPD_barrier:
16405
0
    case OMPD_taskwait:
16406
0
    case OMPD_cancellation_point:
16407
0
    case OMPD_flush:
16408
0
    case OMPD_depobj:
16409
0
    case OMPD_scan:
16410
0
    case OMPD_declare_reduction:
16411
0
    case OMPD_declare_mapper:
16412
0
    case OMPD_declare_simd:
16413
0
    case OMPD_declare_variant:
16414
0
    case OMPD_begin_declare_variant:
16415
0
    case OMPD_end_declare_variant:
16416
0
    case OMPD_declare_target:
16417
0
    case OMPD_end_declare_target:
16418
0
    case OMPD_loop:
16419
0
    case OMPD_teams_loop:
16420
0
    case OMPD_target_teams_loop:
16421
0
    case OMPD_parallel_loop:
16422
0
    case OMPD_target_parallel_loop:
16423
0
    case OMPD_simd:
16424
0
    case OMPD_tile:
16425
0
    case OMPD_unroll:
16426
0
    case OMPD_for:
16427
0
    case OMPD_for_simd:
16428
0
    case OMPD_sections:
16429
0
    case OMPD_section:
16430
0
    case OMPD_single:
16431
0
    case OMPD_master:
16432
0
    case OMPD_masked:
16433
0
    case OMPD_critical:
16434
0
    case OMPD_taskgroup:
16435
0
    case OMPD_distribute:
16436
0
    case OMPD_ordered:
16437
0
    case OMPD_atomic:
16438
0
    case OMPD_distribute_simd:
16439
0
    case OMPD_requires:
16440
0
    case OMPD_metadirective:
16441
0
      llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
16442
0
    case OMPD_unknown:
16443
0
    default:
16444
0
      llvm_unreachable("Unknown OpenMP directive");
16445
0
    }
16446
0
    break;
16447
0
  case OMPC_novariants:
16448
0
  case OMPC_nocontext:
16449
0
    switch (DKind) {
16450
0
    case OMPD_dispatch:
16451
0
      CaptureRegion = OMPD_task;
16452
0
      break;
16453
0
    default:
16454
0
      llvm_unreachable("Unexpected OpenMP directive");
16455
0
    }
16456
0
    break;
16457
0
  case OMPC_filter:
16458
    // Do not capture filter-clause expressions.
16459
0
    break;
16460
0
  case OMPC_when:
16461
0
    if (DKind == OMPD_metadirective) {
16462
0
      CaptureRegion = OMPD_metadirective;
16463
0
    } else if (DKind == OMPD_unknown) {
16464
0
      llvm_unreachable("Unknown OpenMP directive");
16465
0
    } else {
16466
0
      llvm_unreachable("Unexpected OpenMP directive with when clause");
16467
0
    }
16468
0
    break;
16469
0
  case OMPC_firstprivate:
16470
0
  case OMPC_lastprivate:
16471
0
  case OMPC_reduction:
16472
0
  case OMPC_task_reduction:
16473
0
  case OMPC_in_reduction:
16474
0
  case OMPC_linear:
16475
0
  case OMPC_default:
16476
0
  case OMPC_proc_bind:
16477
0
  case OMPC_safelen:
16478
0
  case OMPC_simdlen:
16479
0
  case OMPC_sizes:
16480
0
  case OMPC_allocator:
16481
0
  case OMPC_collapse:
16482
0
  case OMPC_private:
16483
0
  case OMPC_shared:
16484
0
  case OMPC_aligned:
16485
0
  case OMPC_copyin:
16486
0
  case OMPC_copyprivate:
16487
0
  case OMPC_ordered:
16488
0
  case OMPC_nowait:
16489
0
  case OMPC_untied:
16490
0
  case OMPC_mergeable:
16491
0
  case OMPC_threadprivate:
16492
0
  case OMPC_allocate:
16493
0
  case OMPC_flush:
16494
0
  case OMPC_depobj:
16495
0
  case OMPC_read:
16496
0
  case OMPC_write:
16497
0
  case OMPC_update:
16498
0
  case OMPC_capture:
16499
0
  case OMPC_compare:
16500
0
  case OMPC_seq_cst:
16501
0
  case OMPC_acq_rel:
16502
0
  case OMPC_acquire:
16503
0
  case OMPC_release:
16504
0
  case OMPC_relaxed:
16505
0
  case OMPC_depend:
16506
0
  case OMPC_threads:
16507
0
  case OMPC_simd:
16508
0
  case OMPC_map:
16509
0
  case OMPC_nogroup:
16510
0
  case OMPC_hint:
16511
0
  case OMPC_defaultmap:
16512
0
  case OMPC_unknown:
16513
0
  case OMPC_uniform:
16514
0
  case OMPC_to:
16515
0
  case OMPC_from:
16516
0
  case OMPC_use_device_ptr:
16517
0
  case OMPC_use_device_addr:
16518
0
  case OMPC_is_device_ptr:
16519
0
  case OMPC_unified_address:
16520
0
  case OMPC_unified_shared_memory:
16521
0
  case OMPC_reverse_offload:
16522
0
  case OMPC_dynamic_allocators:
16523
0
  case OMPC_atomic_default_mem_order:
16524
0
  case OMPC_device_type:
16525
0
  case OMPC_match:
16526
0
  case OMPC_nontemporal:
16527
0
  case OMPC_order:
16528
0
  case OMPC_at:
16529
0
  case OMPC_severity:
16530
0
  case OMPC_message:
16531
0
  case OMPC_destroy:
16532
0
  case OMPC_detach:
16533
0
  case OMPC_inclusive:
16534
0
  case OMPC_exclusive:
16535
0
  case OMPC_uses_allocators:
16536
0
  case OMPC_affinity:
16537
0
  case OMPC_bind:
16538
0
  default:
16539
0
    llvm_unreachable("Unexpected OpenMP clause.");
16540
0
  }
16541
0
  return CaptureRegion;
16542
0
}
16543
16544
OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
16545
                                     Expr *Condition, SourceLocation StartLoc,
16546
                                     SourceLocation LParenLoc,
16547
                                     SourceLocation NameModifierLoc,
16548
                                     SourceLocation ColonLoc,
16549
0
                                     SourceLocation EndLoc) {
16550
0
  Expr *ValExpr = Condition;
16551
0
  Stmt *HelperValStmt = nullptr;
16552
0
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16553
0
  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16554
0
      !Condition->isInstantiationDependent() &&
16555
0
      !Condition->containsUnexpandedParameterPack()) {
16556
0
    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16557
0
    if (Val.isInvalid())
16558
0
      return nullptr;
16559
16560
0
    ValExpr = Val.get();
16561
16562
0
    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16563
0
    CaptureRegion = getOpenMPCaptureRegionForClause(
16564
0
        DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
16565
0
    if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16566
0
      ValExpr = MakeFullExpr(ValExpr).get();
16567
0
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16568
0
      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16569
0
      HelperValStmt = buildPreInits(Context, Captures);
16570
0
    }
16571
0
  }
16572
16573
0
  return new (Context)
16574
0
      OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16575
0
                  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16576
0
}
16577
16578
OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
16579
                                        SourceLocation StartLoc,
16580
                                        SourceLocation LParenLoc,
16581
0
                                        SourceLocation EndLoc) {
16582
0
  Expr *ValExpr = Condition;
16583
0
  Stmt *HelperValStmt = nullptr;
16584
0
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16585
0
  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16586
0
      !Condition->isInstantiationDependent() &&
16587
0
      !Condition->containsUnexpandedParameterPack()) {
16588
0
    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16589
0
    if (Val.isInvalid())
16590
0
      return nullptr;
16591
16592
0
    ValExpr = MakeFullExpr(Val.get()).get();
16593
16594
0
    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16595
0
    CaptureRegion =
16596
0
        getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
16597
0
    if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16598
0
      ValExpr = MakeFullExpr(ValExpr).get();
16599
0
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16600
0
      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16601
0
      HelperValStmt = buildPreInits(Context, Captures);
16602
0
    }
16603
0
  }
16604
16605
0
  return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
16606
0
                                      StartLoc, LParenLoc, EndLoc);
16607
0
}
16608
16609
ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
16610
0
                                                        Expr *Op) {
16611
0
  if (!Op)
16612
0
    return ExprError();
16613
16614
0
  class IntConvertDiagnoser : public ICEConvertDiagnoser {
16615
0
  public:
16616
0
    IntConvertDiagnoser()
16617
0
        : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
16618
0
    SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
16619
0
                                         QualType T) override {
16620
0
      return S.Diag(Loc, diag::err_omp_not_integral) << T;
16621
0
    }
16622
0
    SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
16623
0
                                             QualType T) override {
16624
0
      return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
16625
0
    }
16626
0
    SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
16627
0
                                               QualType T,
16628
0
                                               QualType ConvTy) override {
16629
0
      return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16630
0
    }
16631
0
    SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
16632
0
                                           QualType ConvTy) override {
16633
0
      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16634
0
             << ConvTy->isEnumeralType() << ConvTy;
16635
0
    }
16636
0
    SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
16637
0
                                            QualType T) override {
16638
0
      return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16639
0
    }
16640
0
    SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
16641
0
                                        QualType ConvTy) override {
16642
0
      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16643
0
             << ConvTy->isEnumeralType() << ConvTy;
16644
0
    }
16645
0
    SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
16646
0
                                             QualType) override {
16647
0
      llvm_unreachable("conversion functions are permitted");
16648
0
    }
16649
0
  } ConvertDiagnoser;
16650
0
  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
16651
0
}
16652
16653
static bool
16654
isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
16655
                          bool StrictlyPositive, bool BuildCapture = false,
16656
                          OpenMPDirectiveKind DKind = OMPD_unknown,
16657
                          OpenMPDirectiveKind *CaptureRegion = nullptr,
16658
0
                          Stmt **HelperValStmt = nullptr) {
16659
0
  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
16660
0
      !ValExpr->isInstantiationDependent()) {
16661
0
    SourceLocation Loc = ValExpr->getExprLoc();
16662
0
    ExprResult Value =
16663
0
        SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
16664
0
    if (Value.isInvalid())
16665
0
      return false;
16666
16667
0
    ValExpr = Value.get();
16668
    // The expression must evaluate to a non-negative integer value.
16669
0
    if (std::optional<llvm::APSInt> Result =
16670
0
            ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
16671
0
      if (Result->isSigned() &&
16672
0
          !((!StrictlyPositive && Result->isNonNegative()) ||
16673
0
            (StrictlyPositive && Result->isStrictlyPositive()))) {
16674
0
        SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
16675
0
            << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16676
0
            << ValExpr->getSourceRange();
16677
0
        return false;
16678
0
      }
16679
0
    }
16680
0
    if (!BuildCapture)
16681
0
      return true;
16682
0
    *CaptureRegion =
16683
0
        getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
16684
0
    if (*CaptureRegion != OMPD_unknown &&
16685
0
        !SemaRef.CurContext->isDependentContext()) {
16686
0
      ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16687
0
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16688
0
      ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16689
0
      *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
16690
0
    }
16691
0
  }
16692
0
  return true;
16693
0
}
16694
16695
OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
16696
                                             SourceLocation StartLoc,
16697
                                             SourceLocation LParenLoc,
16698
0
                                             SourceLocation EndLoc) {
16699
0
  Expr *ValExpr = NumThreads;
16700
0
  Stmt *HelperValStmt = nullptr;
16701
16702
  // OpenMP [2.5, Restrictions]
16703
  //  The num_threads expression must evaluate to a positive integer value.
16704
0
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
16705
0
                                 /*StrictlyPositive=*/true))
16706
0
    return nullptr;
16707
16708
0
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16709
0
  OpenMPDirectiveKind CaptureRegion =
16710
0
      getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
16711
0
  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16712
0
    ValExpr = MakeFullExpr(ValExpr).get();
16713
0
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16714
0
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16715
0
    HelperValStmt = buildPreInits(Context, Captures);
16716
0
  }
16717
16718
0
  return new (Context) OMPNumThreadsClause(
16719
0
      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16720
0
}
16721
16722
ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
16723
                                                       OpenMPClauseKind CKind,
16724
                                                       bool StrictlyPositive,
16725
0
                                                       bool SuppressExprDiags) {
16726
0
  if (!E)
16727
0
    return ExprError();
16728
0
  if (E->isValueDependent() || E->isTypeDependent() ||
16729
0
      E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
16730
0
    return E;
16731
16732
0
  llvm::APSInt Result;
16733
0
  ExprResult ICE;
16734
0
  if (SuppressExprDiags) {
16735
    // Use a custom diagnoser that suppresses 'note' diagnostics about the
16736
    // expression.
16737
0
    struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
16738
0
      SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
16739
0
      Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
16740
0
                                                 SourceLocation Loc) override {
16741
0
        llvm_unreachable("Diagnostic suppressed");
16742
0
      }
16743
0
    } Diagnoser;
16744
0
    ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
16745
0
  } else {
16746
0
    ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
16747
0
  }
16748
0
  if (ICE.isInvalid())
16749
0
    return ExprError();
16750
16751
0
  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
16752
0
      (!StrictlyPositive && !Result.isNonNegative())) {
16753
0
    Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
16754
0
        << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16755
0
        << E->getSourceRange();
16756
0
    return ExprError();
16757
0
  }
16758
0
  if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
16759
0
    Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16760
0
        << E->getSourceRange();
16761
0
    return ExprError();
16762
0
  }
16763
0
  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
16764
0
    DSAStack->setAssociatedLoops(Result.getExtValue());
16765
0
  else if (CKind == OMPC_ordered)
16766
0
    DSAStack->setAssociatedLoops(Result.getExtValue());
16767
0
  return ICE;
16768
0
}
16769
16770
OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
16771
                                          SourceLocation LParenLoc,
16772
0
                                          SourceLocation EndLoc) {
16773
  // OpenMP [2.8.1, simd construct, Description]
16774
  // The parameter of the safelen clause must be a constant
16775
  // positive integer expression.
16776
0
  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
16777
0
  if (Safelen.isInvalid())
16778
0
    return nullptr;
16779
0
  return new (Context)
16780
0
      OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
16781
0
}
16782
16783
OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
16784
                                          SourceLocation LParenLoc,
16785
0
                                          SourceLocation EndLoc) {
16786
  // OpenMP [2.8.1, simd construct, Description]
16787
  // The parameter of the simdlen clause must be a constant
16788
  // positive integer expression.
16789
0
  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
16790
0
  if (Simdlen.isInvalid())
16791
0
    return nullptr;
16792
0
  return new (Context)
16793
0
      OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
16794
0
}
16795
16796
/// Tries to find omp_allocator_handle_t type.
16797
static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
16798
0
                                    DSAStackTy *Stack) {
16799
0
  if (!Stack->getOMPAllocatorHandleT().isNull())
16800
0
    return true;
16801
16802
  // Set the allocator handle type.
16803
0
  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t");
16804
0
  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16805
0
  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16806
0
    S.Diag(Loc, diag::err_omp_implied_type_not_found)
16807
0
        << "omp_allocator_handle_t";
16808
0
    return false;
16809
0
  }
16810
0
  QualType AllocatorHandleEnumTy = PT.get();
16811
0
  AllocatorHandleEnumTy.addConst();
16812
0
  Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
16813
16814
  // Fill the predefined allocator map.
16815
0
  bool ErrorFound = false;
16816
0
  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16817
0
    auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
16818
0
    StringRef Allocator =
16819
0
        OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16820
0
    DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
16821
0
    auto *VD = dyn_cast_or_null<ValueDecl>(
16822
0
        S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
16823
0
    if (!VD) {
16824
0
      ErrorFound = true;
16825
0
      break;
16826
0
    }
16827
0
    QualType AllocatorType =
16828
0
        VD->getType().getNonLValueExprType(S.getASTContext());
16829
0
    ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
16830
0
    if (!Res.isUsable()) {
16831
0
      ErrorFound = true;
16832
0
      break;
16833
0
    }
16834
0
    Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy,
16835
0
                                      Sema::AA_Initializing,
16836
0
                                      /* AllowExplicit */ true);
16837
0
    if (!Res.isUsable()) {
16838
0
      ErrorFound = true;
16839
0
      break;
16840
0
    }
16841
0
    Stack->setAllocator(AllocatorKind, Res.get());
16842
0
  }
16843
0
  if (ErrorFound) {
16844
0
    S.Diag(Loc, diag::err_omp_implied_type_not_found)
16845
0
        << "omp_allocator_handle_t";
16846
0
    return false;
16847
0
  }
16848
16849
0
  return true;
16850
0
}
16851
16852
OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
16853
                                            SourceLocation LParenLoc,
16854
0
                                            SourceLocation EndLoc) {
16855
  // OpenMP [2.11.3, allocate Directive, Description]
16856
  // allocator is an expression of omp_allocator_handle_t type.
16857
0
  if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
16858
0
    return nullptr;
16859
16860
0
  ExprResult Allocator = DefaultLvalueConversion(A);
16861
0
  if (Allocator.isInvalid())
16862
0
    return nullptr;
16863
0
  Allocator = PerformImplicitConversion(Allocator.get(),
16864
0
                                        DSAStack->getOMPAllocatorHandleT(),
16865
0
                                        Sema::AA_Initializing,
16866
0
                                        /*AllowExplicit=*/true);
16867
0
  if (Allocator.isInvalid())
16868
0
    return nullptr;
16869
0
  return new (Context)
16870
0
      OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
16871
0
}
16872
16873
OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
16874
                                           SourceLocation StartLoc,
16875
                                           SourceLocation LParenLoc,
16876
0
                                           SourceLocation EndLoc) {
16877
  // OpenMP [2.7.1, loop construct, Description]
16878
  // OpenMP [2.8.1, simd construct, Description]
16879
  // OpenMP [2.9.6, distribute construct, Description]
16880
  // The parameter of the collapse clause must be a constant
16881
  // positive integer expression.
16882
0
  ExprResult NumForLoopsResult =
16883
0
      VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
16884
0
  if (NumForLoopsResult.isInvalid())
16885
0
    return nullptr;
16886
0
  return new (Context)
16887
0
      OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
16888
0
}
16889
16890
OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
16891
                                          SourceLocation EndLoc,
16892
                                          SourceLocation LParenLoc,
16893
0
                                          Expr *NumForLoops) {
16894
  // OpenMP [2.7.1, loop construct, Description]
16895
  // OpenMP [2.8.1, simd construct, Description]
16896
  // OpenMP [2.9.6, distribute construct, Description]
16897
  // The parameter of the ordered clause must be a constant
16898
  // positive integer expression if any.
16899
0
  if (NumForLoops && LParenLoc.isValid()) {
16900
0
    ExprResult NumForLoopsResult =
16901
0
        VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
16902
0
    if (NumForLoopsResult.isInvalid())
16903
0
      return nullptr;
16904
0
    NumForLoops = NumForLoopsResult.get();
16905
0
  } else {
16906
0
    NumForLoops = nullptr;
16907
0
  }
16908
0
  auto *Clause = OMPOrderedClause::Create(
16909
0
      Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
16910
0
      StartLoc, LParenLoc, EndLoc);
16911
0
  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
16912
0
  return Clause;
16913
0
}
16914
16915
OMPClause *Sema::ActOnOpenMPSimpleClause(
16916
    OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
16917
0
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16918
0
  OMPClause *Res = nullptr;
16919
0
  switch (Kind) {
16920
0
  case OMPC_default:
16921
0
    Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
16922
0
                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16923
0
    break;
16924
0
  case OMPC_proc_bind:
16925
0
    Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
16926
0
                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16927
0
    break;
16928
0
  case OMPC_atomic_default_mem_order:
16929
0
    Res = ActOnOpenMPAtomicDefaultMemOrderClause(
16930
0
        static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
16931
0
        ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16932
0
    break;
16933
0
  case OMPC_fail:
16934
0
    Res = ActOnOpenMPFailClause(
16935
0
        static_cast<OpenMPClauseKind>(Argument),
16936
0
        ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16937
0
    break;
16938
0
  case OMPC_update:
16939
0
    Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
16940
0
                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16941
0
    break;
16942
0
  case OMPC_bind:
16943
0
    Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
16944
0
                                ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16945
0
    break;
16946
0
  case OMPC_at:
16947
0
    Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
16948
0
                              ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16949
0
    break;
16950
0
  case OMPC_severity:
16951
0
    Res = ActOnOpenMPSeverityClause(
16952
0
        static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
16953
0
        LParenLoc, EndLoc);
16954
0
    break;
16955
0
  case OMPC_if:
16956
0
  case OMPC_final:
16957
0
  case OMPC_num_threads:
16958
0
  case OMPC_safelen:
16959
0
  case OMPC_simdlen:
16960
0
  case OMPC_sizes:
16961
0
  case OMPC_allocator:
16962
0
  case OMPC_collapse:
16963
0
  case OMPC_schedule:
16964
0
  case OMPC_private:
16965
0
  case OMPC_firstprivate:
16966
0
  case OMPC_lastprivate:
16967
0
  case OMPC_shared:
16968
0
  case OMPC_reduction:
16969
0
  case OMPC_task_reduction:
16970
0
  case OMPC_in_reduction:
16971
0
  case OMPC_linear:
16972
0
  case OMPC_aligned:
16973
0
  case OMPC_copyin:
16974
0
  case OMPC_copyprivate:
16975
0
  case OMPC_ordered:
16976
0
  case OMPC_nowait:
16977
0
  case OMPC_untied:
16978
0
  case OMPC_mergeable:
16979
0
  case OMPC_threadprivate:
16980
0
  case OMPC_allocate:
16981
0
  case OMPC_flush:
16982
0
  case OMPC_depobj:
16983
0
  case OMPC_read:
16984
0
  case OMPC_write:
16985
0
  case OMPC_capture:
16986
0
  case OMPC_compare:
16987
0
  case OMPC_seq_cst:
16988
0
  case OMPC_acq_rel:
16989
0
  case OMPC_acquire:
16990
0
  case OMPC_release:
16991
0
  case OMPC_relaxed:
16992
0
  case OMPC_depend:
16993
0
  case OMPC_device:
16994
0
  case OMPC_threads:
16995
0
  case OMPC_simd:
16996
0
  case OMPC_map:
16997
0
  case OMPC_num_teams:
16998
0
  case OMPC_thread_limit:
16999
0
  case OMPC_priority:
17000
0
  case OMPC_grainsize:
17001
0
  case OMPC_nogroup:
17002
0
  case OMPC_num_tasks:
17003
0
  case OMPC_hint:
17004
0
  case OMPC_dist_schedule:
17005
0
  case OMPC_defaultmap:
17006
0
  case OMPC_unknown:
17007
0
  case OMPC_uniform:
17008
0
  case OMPC_to:
17009
0
  case OMPC_from:
17010
0
  case OMPC_use_device_ptr:
17011
0
  case OMPC_use_device_addr:
17012
0
  case OMPC_is_device_ptr:
17013
0
  case OMPC_has_device_addr:
17014
0
  case OMPC_unified_address:
17015
0
  case OMPC_unified_shared_memory:
17016
0
  case OMPC_reverse_offload:
17017
0
  case OMPC_dynamic_allocators:
17018
0
  case OMPC_device_type:
17019
0
  case OMPC_match:
17020
0
  case OMPC_nontemporal:
17021
0
  case OMPC_destroy:
17022
0
  case OMPC_novariants:
17023
0
  case OMPC_nocontext:
17024
0
  case OMPC_detach:
17025
0
  case OMPC_inclusive:
17026
0
  case OMPC_exclusive:
17027
0
  case OMPC_uses_allocators:
17028
0
  case OMPC_affinity:
17029
0
  case OMPC_when:
17030
0
  case OMPC_message:
17031
0
  default:
17032
0
    llvm_unreachable("Clause is not allowed.");
17033
0
  }
17034
0
  return Res;
17035
0
}
17036
17037
static std::string
17038
getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
17039
0
                        ArrayRef<unsigned> Exclude = std::nullopt) {
17040
0
  SmallString<256> Buffer;
17041
0
  llvm::raw_svector_ostream Out(Buffer);
17042
0
  unsigned Skipped = Exclude.size();
17043
0
  for (unsigned I = First; I < Last; ++I) {
17044
0
    if (llvm::is_contained(Exclude, I)) {
17045
0
      --Skipped;
17046
0
      continue;
17047
0
    }
17048
0
    Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
17049
0
    if (I + Skipped + 2 == Last)
17050
0
      Out << " or ";
17051
0
    else if (I + Skipped + 1 != Last)
17052
0
      Out << ", ";
17053
0
  }
17054
0
  return std::string(Out.str());
17055
0
}
17056
17057
OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
17058
                                          SourceLocation KindKwLoc,
17059
                                          SourceLocation StartLoc,
17060
                                          SourceLocation LParenLoc,
17061
0
                                          SourceLocation EndLoc) {
17062
0
  if (Kind == OMP_DEFAULT_unknown) {
17063
0
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17064
0
        << getListOfPossibleValues(OMPC_default, /*First=*/0,
17065
0
                                   /*Last=*/unsigned(OMP_DEFAULT_unknown))
17066
0
        << getOpenMPClauseName(OMPC_default);
17067
0
    return nullptr;
17068
0
  }
17069
17070
0
  switch (Kind) {
17071
0
  case OMP_DEFAULT_none:
17072
0
    DSAStack->setDefaultDSANone(KindKwLoc);
17073
0
    break;
17074
0
  case OMP_DEFAULT_shared:
17075
0
    DSAStack->setDefaultDSAShared(KindKwLoc);
17076
0
    break;
17077
0
  case OMP_DEFAULT_firstprivate:
17078
0
    DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
17079
0
    break;
17080
0
  case OMP_DEFAULT_private:
17081
0
    DSAStack->setDefaultDSAPrivate(KindKwLoc);
17082
0
    break;
17083
0
  default:
17084
0
    llvm_unreachable("DSA unexpected in OpenMP default clause");
17085
0
  }
17086
17087
0
  return new (Context)
17088
0
      OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17089
0
}
17090
17091
OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
17092
                                           SourceLocation KindKwLoc,
17093
                                           SourceLocation StartLoc,
17094
                                           SourceLocation LParenLoc,
17095
0
                                           SourceLocation EndLoc) {
17096
0
  if (Kind == OMP_PROC_BIND_unknown) {
17097
0
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17098
0
        << getListOfPossibleValues(OMPC_proc_bind,
17099
0
                                   /*First=*/unsigned(OMP_PROC_BIND_master),
17100
                                   /*Last=*/
17101
0
                                   unsigned(LangOpts.OpenMP > 50
17102
0
                                                ? OMP_PROC_BIND_primary
17103
0
                                                : OMP_PROC_BIND_spread) +
17104
0
                                       1)
17105
0
        << getOpenMPClauseName(OMPC_proc_bind);
17106
0
    return nullptr;
17107
0
  }
17108
0
  if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
17109
0
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17110
0
        << getListOfPossibleValues(OMPC_proc_bind,
17111
0
                                   /*First=*/unsigned(OMP_PROC_BIND_master),
17112
                                   /*Last=*/
17113
0
                                   unsigned(OMP_PROC_BIND_spread) + 1)
17114
0
        << getOpenMPClauseName(OMPC_proc_bind);
17115
0
  return new (Context)
17116
0
      OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17117
0
}
17118
17119
OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
17120
    OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
17121
0
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
17122
0
  if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
17123
0
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17124
0
        << getListOfPossibleValues(
17125
0
               OMPC_atomic_default_mem_order, /*First=*/0,
17126
0
               /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
17127
0
        << getOpenMPClauseName(OMPC_atomic_default_mem_order);
17128
0
    return nullptr;
17129
0
  }
17130
0
  return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
17131
0
                                                      LParenLoc, EndLoc);
17132
0
}
17133
17134
OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
17135
                                     SourceLocation KindKwLoc,
17136
                                     SourceLocation StartLoc,
17137
                                     SourceLocation LParenLoc,
17138
0
                                     SourceLocation EndLoc) {
17139
0
  if (Kind == OMPC_AT_unknown) {
17140
0
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17141
0
        << getListOfPossibleValues(OMPC_at, /*First=*/0,
17142
0
                                   /*Last=*/OMPC_AT_unknown)
17143
0
        << getOpenMPClauseName(OMPC_at);
17144
0
    return nullptr;
17145
0
  }
17146
0
  return new (Context)
17147
0
      OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17148
0
}
17149
17150
OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
17151
                                           SourceLocation KindKwLoc,
17152
                                           SourceLocation StartLoc,
17153
                                           SourceLocation LParenLoc,
17154
0
                                           SourceLocation EndLoc) {
17155
0
  if (Kind == OMPC_SEVERITY_unknown) {
17156
0
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17157
0
        << getListOfPossibleValues(OMPC_severity, /*First=*/0,
17158
0
                                   /*Last=*/OMPC_SEVERITY_unknown)
17159
0
        << getOpenMPClauseName(OMPC_severity);
17160
0
    return nullptr;
17161
0
  }
17162
0
  return new (Context)
17163
0
      OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17164
0
}
17165
17166
OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc,
17167
                                          SourceLocation LParenLoc,
17168
0
                                          SourceLocation EndLoc) {
17169
0
  assert(ME && "NULL expr in Message clause");
17170
0
  if (!isa<StringLiteral>(ME)) {
17171
0
    Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
17172
0
        << getOpenMPClauseName(OMPC_message);
17173
0
    return nullptr;
17174
0
  }
17175
0
  return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
17176
0
}
17177
17178
OMPClause *Sema::ActOnOpenMPOrderClause(
17179
    OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind,
17180
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
17181
0
    SourceLocation KindLoc, SourceLocation EndLoc) {
17182
0
  if (Kind != OMPC_ORDER_concurrent ||
17183
0
      (LangOpts.OpenMP < 51 && MLoc.isValid())) {
17184
    // Kind should be concurrent,
17185
    // Modifiers introduced in OpenMP 5.1
17186
0
    static_assert(OMPC_ORDER_unknown > 0,
17187
0
                  "OMPC_ORDER_unknown not greater than 0");
17188
17189
0
    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17190
0
        << getListOfPossibleValues(OMPC_order,
17191
0
                                   /*First=*/0,
17192
0
                                   /*Last=*/OMPC_ORDER_unknown)
17193
0
        << getOpenMPClauseName(OMPC_order);
17194
0
    return nullptr;
17195
0
  }
17196
0
  if (LangOpts.OpenMP >= 51) {
17197
0
    if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) {
17198
0
      Diag(MLoc, diag::err_omp_unexpected_clause_value)
17199
0
          << getListOfPossibleValues(OMPC_order,
17200
0
                                     /*First=*/OMPC_ORDER_MODIFIER_unknown + 1,
17201
0
                                     /*Last=*/OMPC_ORDER_MODIFIER_last)
17202
0
          << getOpenMPClauseName(OMPC_order);
17203
0
    } else {
17204
0
      DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true);
17205
0
      if (DSAStack->getCurScope()) {
17206
        // mark the current scope with 'order' flag
17207
0
        unsigned existingFlags = DSAStack->getCurScope()->getFlags();
17208
0
        DSAStack->getCurScope()->setFlags(existingFlags |
17209
0
                                          Scope::OpenMPOrderClauseScope);
17210
0
      }
17211
0
    }
17212
0
  }
17213
0
  return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc,
17214
0
                                      EndLoc, Modifier, MLoc);
17215
0
}
17216
17217
OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
17218
                                         SourceLocation KindKwLoc,
17219
                                         SourceLocation StartLoc,
17220
                                         SourceLocation LParenLoc,
17221
0
                                         SourceLocation EndLoc) {
17222
0
  if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
17223
0
      Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
17224
0
    SmallVector<unsigned> Except = {
17225
0
        OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
17226
0
        OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
17227
0
    if (LangOpts.OpenMP < 51)
17228
0
      Except.push_back(OMPC_DEPEND_inoutset);
17229
0
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17230
0
        << getListOfPossibleValues(OMPC_depend, /*First=*/0,
17231
0
                                   /*Last=*/OMPC_DEPEND_unknown, Except)
17232
0
        << getOpenMPClauseName(OMPC_update);
17233
0
    return nullptr;
17234
0
  }
17235
0
  return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
17236
0
                                 EndLoc);
17237
0
}
17238
17239
OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
17240
                                        SourceLocation StartLoc,
17241
                                        SourceLocation LParenLoc,
17242
0
                                        SourceLocation EndLoc) {
17243
0
  for (Expr *SizeExpr : SizeExprs) {
17244
0
    ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
17245
0
        SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
17246
0
    if (!NumForLoopsResult.isUsable())
17247
0
      return nullptr;
17248
0
  }
17249
17250
0
  DSAStack->setAssociatedLoops(SizeExprs.size());
17251
0
  return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17252
0
                                SizeExprs);
17253
0
}
17254
17255
OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
17256
0
                                       SourceLocation EndLoc) {
17257
0
  return OMPFullClause::Create(Context, StartLoc, EndLoc);
17258
0
}
17259
17260
OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
17261
                                          SourceLocation StartLoc,
17262
                                          SourceLocation LParenLoc,
17263
0
                                          SourceLocation EndLoc) {
17264
0
  if (FactorExpr) {
17265
    // If an argument is specified, it must be a constant (or an unevaluated
17266
    // template expression).
17267
0
    ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
17268
0
        FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
17269
0
    if (FactorResult.isInvalid())
17270
0
      return nullptr;
17271
0
    FactorExpr = FactorResult.get();
17272
0
  }
17273
17274
0
  return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17275
0
                                  FactorExpr);
17276
0
}
17277
17278
OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
17279
                                        SourceLocation LParenLoc,
17280
0
                                        SourceLocation EndLoc) {
17281
0
  ExprResult AlignVal;
17282
0
  AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
17283
0
  if (AlignVal.isInvalid())
17284
0
    return nullptr;
17285
0
  return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
17286
0
                                EndLoc);
17287
0
}
17288
17289
OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
17290
    OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
17291
    SourceLocation StartLoc, SourceLocation LParenLoc,
17292
    ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
17293
0
    SourceLocation EndLoc) {
17294
0
  OMPClause *Res = nullptr;
17295
0
  switch (Kind) {
17296
0
  case OMPC_schedule:
17297
0
    enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
17298
0
    assert(Argument.size() == NumberOfElements &&
17299
0
           ArgumentLoc.size() == NumberOfElements);
17300
0
    Res = ActOnOpenMPScheduleClause(
17301
0
        static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
17302
0
        static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
17303
0
        static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
17304
0
        StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
17305
0
        ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
17306
0
    break;
17307
0
  case OMPC_if:
17308
0
    assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17309
0
    Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
17310
0
                              Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
17311
0
                              DelimLoc, EndLoc);
17312
0
    break;
17313
0
  case OMPC_dist_schedule:
17314
0
    Res = ActOnOpenMPDistScheduleClause(
17315
0
        static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
17316
0
        StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
17317
0
    break;
17318
0
  case OMPC_defaultmap:
17319
0
    enum { Modifier, DefaultmapKind };
17320
0
    Res = ActOnOpenMPDefaultmapClause(
17321
0
        static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
17322
0
        static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
17323
0
        StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
17324
0
        EndLoc);
17325
0
    break;
17326
0
  case OMPC_order:
17327
0
    enum { OrderModifier, OrderKind };
17328
0
    Res = ActOnOpenMPOrderClause(
17329
0
        static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]),
17330
0
        static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc,
17331
0
        LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
17332
0
    break;
17333
0
  case OMPC_device:
17334
0
    assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17335
0
    Res = ActOnOpenMPDeviceClause(
17336
0
        static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
17337
0
        StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17338
0
    break;
17339
0
  case OMPC_grainsize:
17340
0
    assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17341
0
           "Modifier for grainsize clause and its location are expected.");
17342
0
    Res = ActOnOpenMPGrainsizeClause(
17343
0
        static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr,
17344
0
        StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17345
0
    break;
17346
0
  case OMPC_num_tasks:
17347
0
    assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17348
0
           "Modifier for num_tasks clause and its location are expected.");
17349
0
    Res = ActOnOpenMPNumTasksClause(
17350
0
        static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
17351
0
        StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17352
0
    break;
17353
0
  case OMPC_final:
17354
0
  case OMPC_num_threads:
17355
0
  case OMPC_safelen:
17356
0
  case OMPC_simdlen:
17357
0
  case OMPC_sizes:
17358
0
  case OMPC_allocator:
17359
0
  case OMPC_collapse:
17360
0
  case OMPC_default:
17361
0
  case OMPC_proc_bind:
17362
0
  case OMPC_private:
17363
0
  case OMPC_firstprivate:
17364
0
  case OMPC_lastprivate:
17365
0
  case OMPC_shared:
17366
0
  case OMPC_reduction:
17367
0
  case OMPC_task_reduction:
17368
0
  case OMPC_in_reduction:
17369
0
  case OMPC_linear:
17370
0
  case OMPC_aligned:
17371
0
  case OMPC_copyin:
17372
0
  case OMPC_copyprivate:
17373
0
  case OMPC_ordered:
17374
0
  case OMPC_nowait:
17375
0
  case OMPC_untied:
17376
0
  case OMPC_mergeable:
17377
0
  case OMPC_threadprivate:
17378
0
  case OMPC_allocate:
17379
0
  case OMPC_flush:
17380
0
  case OMPC_depobj:
17381
0
  case OMPC_read:
17382
0
  case OMPC_write:
17383
0
  case OMPC_update:
17384
0
  case OMPC_capture:
17385
0
  case OMPC_compare:
17386
0
  case OMPC_seq_cst:
17387
0
  case OMPC_acq_rel:
17388
0
  case OMPC_acquire:
17389
0
  case OMPC_release:
17390
0
  case OMPC_relaxed:
17391
0
  case OMPC_depend:
17392
0
  case OMPC_threads:
17393
0
  case OMPC_simd:
17394
0
  case OMPC_map:
17395
0
  case OMPC_num_teams:
17396
0
  case OMPC_thread_limit:
17397
0
  case OMPC_priority:
17398
0
  case OMPC_nogroup:
17399
0
  case OMPC_hint:
17400
0
  case OMPC_unknown:
17401
0
  case OMPC_uniform:
17402
0
  case OMPC_to:
17403
0
  case OMPC_from:
17404
0
  case OMPC_use_device_ptr:
17405
0
  case OMPC_use_device_addr:
17406
0
  case OMPC_is_device_ptr:
17407
0
  case OMPC_has_device_addr:
17408
0
  case OMPC_unified_address:
17409
0
  case OMPC_unified_shared_memory:
17410
0
  case OMPC_reverse_offload:
17411
0
  case OMPC_dynamic_allocators:
17412
0
  case OMPC_atomic_default_mem_order:
17413
0
  case OMPC_device_type:
17414
0
  case OMPC_match:
17415
0
  case OMPC_nontemporal:
17416
0
  case OMPC_at:
17417
0
  case OMPC_severity:
17418
0
  case OMPC_message:
17419
0
  case OMPC_destroy:
17420
0
  case OMPC_novariants:
17421
0
  case OMPC_nocontext:
17422
0
  case OMPC_detach:
17423
0
  case OMPC_inclusive:
17424
0
  case OMPC_exclusive:
17425
0
  case OMPC_uses_allocators:
17426
0
  case OMPC_affinity:
17427
0
  case OMPC_when:
17428
0
  case OMPC_bind:
17429
0
  default:
17430
0
    llvm_unreachable("Clause is not allowed.");
17431
0
  }
17432
0
  return Res;
17433
0
}
17434
17435
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
17436
                                   OpenMPScheduleClauseModifier M2,
17437
0
                                   SourceLocation M1Loc, SourceLocation M2Loc) {
17438
0
  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
17439
0
    SmallVector<unsigned, 2> Excluded;
17440
0
    if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
17441
0
      Excluded.push_back(M2);
17442
0
    if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17443
0
      Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17444
0
    if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17445
0
      Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17446
0
    S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17447
0
        << getListOfPossibleValues(OMPC_schedule,
17448
0
                                   /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
17449
0
                                   /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17450
0
                                   Excluded)
17451
0
        << getOpenMPClauseName(OMPC_schedule);
17452
0
    return true;
17453
0
  }
17454
0
  return false;
17455
0
}
17456
17457
OMPClause *Sema::ActOnOpenMPScheduleClause(
17458
    OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
17459
    OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
17460
    SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
17461
0
    SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
17462
0
  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
17463
0
      checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
17464
0
    return nullptr;
17465
  // OpenMP, 2.7.1, Loop Construct, Restrictions
17466
  // Either the monotonic modifier or the nonmonotonic modifier can be specified
17467
  // but not both.
17468
0
  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
17469
0
      (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
17470
0
       M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
17471
0
      (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
17472
0
       M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
17473
0
    Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17474
0
        << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
17475
0
        << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
17476
0
    return nullptr;
17477
0
  }
17478
0
  if (Kind == OMPC_SCHEDULE_unknown) {
17479
0
    std::string Values;
17480
0
    if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
17481
0
      unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
17482
0
      Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17483
0
                                       /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17484
0
                                       Exclude);
17485
0
    } else {
17486
0
      Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17487
0
                                       /*Last=*/OMPC_SCHEDULE_unknown);
17488
0
    }
17489
0
    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17490
0
        << Values << getOpenMPClauseName(OMPC_schedule);
17491
0
    return nullptr;
17492
0
  }
17493
  // OpenMP, 2.7.1, Loop Construct, Restrictions
17494
  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
17495
  // schedule(guided).
17496
  // OpenMP 5.0 does not have this restriction.
17497
0
  if (LangOpts.OpenMP < 50 &&
17498
0
      (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
17499
0
       M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
17500
0
      Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
17501
0
    Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
17502
0
         diag::err_omp_schedule_nonmonotonic_static);
17503
0
    return nullptr;
17504
0
  }
17505
0
  Expr *ValExpr = ChunkSize;
17506
0
  Stmt *HelperValStmt = nullptr;
17507
0
  if (ChunkSize) {
17508
0
    if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
17509
0
        !ChunkSize->isInstantiationDependent() &&
17510
0
        !ChunkSize->containsUnexpandedParameterPack()) {
17511
0
      SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
17512
0
      ExprResult Val =
17513
0
          PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
17514
0
      if (Val.isInvalid())
17515
0
        return nullptr;
17516
17517
0
      ValExpr = Val.get();
17518
17519
      // OpenMP [2.7.1, Restrictions]
17520
      //  chunk_size must be a loop invariant integer expression with a positive
17521
      //  value.
17522
0
      if (std::optional<llvm::APSInt> Result =
17523
0
              ValExpr->getIntegerConstantExpr(Context)) {
17524
0
        if (Result->isSigned() && !Result->isStrictlyPositive()) {
17525
0
          Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17526
0
              << "schedule" << 1 << ChunkSize->getSourceRange();
17527
0
          return nullptr;
17528
0
        }
17529
0
      } else if (getOpenMPCaptureRegionForClause(
17530
0
                     DSAStack->getCurrentDirective(), OMPC_schedule,
17531
0
                     LangOpts.OpenMP) != OMPD_unknown &&
17532
0
                 !CurContext->isDependentContext()) {
17533
0
        ValExpr = MakeFullExpr(ValExpr).get();
17534
0
        llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17535
0
        ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17536
0
        HelperValStmt = buildPreInits(Context, Captures);
17537
0
      }
17538
0
    }
17539
0
  }
17540
17541
0
  return new (Context)
17542
0
      OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
17543
0
                        ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17544
0
}
17545
17546
OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
17547
                                   SourceLocation StartLoc,
17548
0
                                   SourceLocation EndLoc) {
17549
0
  OMPClause *Res = nullptr;
17550
0
  switch (Kind) {
17551
0
  case OMPC_ordered:
17552
0
    Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
17553
0
    break;
17554
0
  case OMPC_nowait:
17555
0
    Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
17556
0
    break;
17557
0
  case OMPC_untied:
17558
0
    Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
17559
0
    break;
17560
0
  case OMPC_mergeable:
17561
0
    Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
17562
0
    break;
17563
0
  case OMPC_read:
17564
0
    Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
17565
0
    break;
17566
0
  case OMPC_write:
17567
0
    Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
17568
0
    break;
17569
0
  case OMPC_update:
17570
0
    Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
17571
0
    break;
17572
0
  case OMPC_capture:
17573
0
    Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
17574
0
    break;
17575
0
  case OMPC_compare:
17576
0
    Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
17577
0
    break;
17578
0
  case OMPC_fail:
17579
0
    Res = ActOnOpenMPFailClause(StartLoc, EndLoc);
17580
0
    break;
17581
0
  case OMPC_seq_cst:
17582
0
    Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
17583
0
    break;
17584
0
  case OMPC_acq_rel:
17585
0
    Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
17586
0
    break;
17587
0
  case OMPC_acquire:
17588
0
    Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
17589
0
    break;
17590
0
  case OMPC_release:
17591
0
    Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
17592
0
    break;
17593
0
  case OMPC_relaxed:
17594
0
    Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
17595
0
    break;
17596
0
  case OMPC_threads:
17597
0
    Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
17598
0
    break;
17599
0
  case OMPC_simd:
17600
0
    Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
17601
0
    break;
17602
0
  case OMPC_nogroup:
17603
0
    Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
17604
0
    break;
17605
0
  case OMPC_unified_address:
17606
0
    Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
17607
0
    break;
17608
0
  case OMPC_unified_shared_memory:
17609
0
    Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17610
0
    break;
17611
0
  case OMPC_reverse_offload:
17612
0
    Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
17613
0
    break;
17614
0
  case OMPC_dynamic_allocators:
17615
0
    Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
17616
0
    break;
17617
0
  case OMPC_destroy:
17618
0
    Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
17619
0
                                   /*LParenLoc=*/SourceLocation(),
17620
0
                                   /*VarLoc=*/SourceLocation(), EndLoc);
17621
0
    break;
17622
0
  case OMPC_full:
17623
0
    Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
17624
0
    break;
17625
0
  case OMPC_partial:
17626
0
    Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
17627
0
    break;
17628
0
  case OMPC_ompx_bare:
17629
0
    Res = ActOnOpenMPXBareClause(StartLoc, EndLoc);
17630
0
    break;
17631
0
  case OMPC_if:
17632
0
  case OMPC_final:
17633
0
  case OMPC_num_threads:
17634
0
  case OMPC_safelen:
17635
0
  case OMPC_simdlen:
17636
0
  case OMPC_sizes:
17637
0
  case OMPC_allocator:
17638
0
  case OMPC_collapse:
17639
0
  case OMPC_schedule:
17640
0
  case OMPC_private:
17641
0
  case OMPC_firstprivate:
17642
0
  case OMPC_lastprivate:
17643
0
  case OMPC_shared:
17644
0
  case OMPC_reduction:
17645
0
  case OMPC_task_reduction:
17646
0
  case OMPC_in_reduction:
17647
0
  case OMPC_linear:
17648
0
  case OMPC_aligned:
17649
0
  case OMPC_copyin:
17650
0
  case OMPC_copyprivate:
17651
0
  case OMPC_default:
17652
0
  case OMPC_proc_bind:
17653
0
  case OMPC_threadprivate:
17654
0
  case OMPC_allocate:
17655
0
  case OMPC_flush:
17656
0
  case OMPC_depobj:
17657
0
  case OMPC_depend:
17658
0
  case OMPC_device:
17659
0
  case OMPC_map:
17660
0
  case OMPC_num_teams:
17661
0
  case OMPC_thread_limit:
17662
0
  case OMPC_priority:
17663
0
  case OMPC_grainsize:
17664
0
  case OMPC_num_tasks:
17665
0
  case OMPC_hint:
17666
0
  case OMPC_dist_schedule:
17667
0
  case OMPC_defaultmap:
17668
0
  case OMPC_unknown:
17669
0
  case OMPC_uniform:
17670
0
  case OMPC_to:
17671
0
  case OMPC_from:
17672
0
  case OMPC_use_device_ptr:
17673
0
  case OMPC_use_device_addr:
17674
0
  case OMPC_is_device_ptr:
17675
0
  case OMPC_has_device_addr:
17676
0
  case OMPC_atomic_default_mem_order:
17677
0
  case OMPC_device_type:
17678
0
  case OMPC_match:
17679
0
  case OMPC_nontemporal:
17680
0
  case OMPC_order:
17681
0
  case OMPC_at:
17682
0
  case OMPC_severity:
17683
0
  case OMPC_message:
17684
0
  case OMPC_novariants:
17685
0
  case OMPC_nocontext:
17686
0
  case OMPC_detach:
17687
0
  case OMPC_inclusive:
17688
0
  case OMPC_exclusive:
17689
0
  case OMPC_uses_allocators:
17690
0
  case OMPC_affinity:
17691
0
  case OMPC_when:
17692
0
  case OMPC_ompx_dyn_cgroup_mem:
17693
0
  default:
17694
0
    llvm_unreachable("Clause is not allowed.");
17695
0
  }
17696
0
  return Res;
17697
0
}
17698
17699
OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
17700
0
                                         SourceLocation EndLoc) {
17701
0
  DSAStack->setNowaitRegion();
17702
0
  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
17703
0
}
17704
17705
OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
17706
0
                                         SourceLocation EndLoc) {
17707
0
  DSAStack->setUntiedRegion();
17708
0
  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
17709
0
}
17710
17711
OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
17712
0
                                            SourceLocation EndLoc) {
17713
0
  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
17714
0
}
17715
17716
OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
17717
0
                                       SourceLocation EndLoc) {
17718
0
  return new (Context) OMPReadClause(StartLoc, EndLoc);
17719
0
}
17720
17721
OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
17722
0
                                        SourceLocation EndLoc) {
17723
0
  return new (Context) OMPWriteClause(StartLoc, EndLoc);
17724
0
}
17725
17726
OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
17727
0
                                         SourceLocation EndLoc) {
17728
0
  return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
17729
0
}
17730
17731
OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
17732
0
                                          SourceLocation EndLoc) {
17733
0
  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
17734
0
}
17735
17736
OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
17737
0
                                          SourceLocation EndLoc) {
17738
0
  return new (Context) OMPCompareClause(StartLoc, EndLoc);
17739
0
}
17740
17741
OMPClause *Sema::ActOnOpenMPFailClause(SourceLocation StartLoc,
17742
0
                                       SourceLocation EndLoc) {
17743
0
  return new (Context) OMPFailClause(StartLoc, EndLoc);
17744
0
}
17745
17746
OMPClause *Sema::ActOnOpenMPFailClause(
17747
      OpenMPClauseKind Parameter, SourceLocation KindLoc,
17748
      SourceLocation StartLoc, SourceLocation LParenLoc,
17749
0
      SourceLocation EndLoc) {
17750
17751
0
  if (!checkFailClauseParameter(Parameter)) {
17752
0
    Diag(KindLoc, diag::err_omp_atomic_fail_wrong_or_no_clauses);
17753
0
    return nullptr;
17754
0
  }
17755
0
  return new (Context)
17756
0
      OMPFailClause(Parameter, KindLoc, StartLoc, LParenLoc, EndLoc);
17757
0
}
17758
17759
OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
17760
0
                                         SourceLocation EndLoc) {
17761
0
  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
17762
0
}
17763
17764
OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
17765
0
                                         SourceLocation EndLoc) {
17766
0
  return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
17767
0
}
17768
17769
OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
17770
0
                                          SourceLocation EndLoc) {
17771
0
  return new (Context) OMPAcquireClause(StartLoc, EndLoc);
17772
0
}
17773
17774
OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
17775
0
                                          SourceLocation EndLoc) {
17776
0
  return new (Context) OMPReleaseClause(StartLoc, EndLoc);
17777
0
}
17778
17779
OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
17780
0
                                          SourceLocation EndLoc) {
17781
0
  return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
17782
0
}
17783
17784
OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
17785
0
                                          SourceLocation EndLoc) {
17786
0
  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
17787
0
}
17788
17789
OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
17790
0
                                       SourceLocation EndLoc) {
17791
0
  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
17792
0
}
17793
17794
OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
17795
0
                                          SourceLocation EndLoc) {
17796
0
  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
17797
0
}
17798
17799
OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
17800
0
                                                 SourceLocation EndLoc) {
17801
0
  return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
17802
0
}
17803
17804
OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
17805
0
                                                      SourceLocation EndLoc) {
17806
0
  return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17807
0
}
17808
17809
OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
17810
0
                                                 SourceLocation EndLoc) {
17811
0
  return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
17812
0
}
17813
17814
OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
17815
0
                                                    SourceLocation EndLoc) {
17816
0
  return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
17817
0
}
17818
17819
StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
17820
                                             SourceLocation StartLoc,
17821
0
                                             SourceLocation EndLoc) {
17822
17823
  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17824
  // At least one action-clause must appear on a directive.
17825
0
  if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17826
0
    StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
17827
0
    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17828
0
        << Expected << getOpenMPDirectiveName(OMPD_interop);
17829
0
    return StmtError();
17830
0
  }
17831
17832
  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17833
  // A depend clause can only appear on the directive if a targetsync
17834
  // interop-type is present or the interop-var was initialized with
17835
  // the targetsync interop-type.
17836
17837
  // If there is any 'init' clause diagnose if there is no 'init' clause with
17838
  // interop-type of 'targetsync'. Cases involving other directives cannot be
17839
  // diagnosed.
17840
0
  const OMPDependClause *DependClause = nullptr;
17841
0
  bool HasInitClause = false;
17842
0
  bool IsTargetSync = false;
17843
0
  for (const OMPClause *C : Clauses) {
17844
0
    if (IsTargetSync)
17845
0
      break;
17846
0
    if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
17847
0
      HasInitClause = true;
17848
0
      if (InitClause->getIsTargetSync())
17849
0
        IsTargetSync = true;
17850
0
    } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
17851
0
      DependClause = DC;
17852
0
    }
17853
0
  }
17854
0
  if (DependClause && HasInitClause && !IsTargetSync) {
17855
0
    Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17856
0
    return StmtError();
17857
0
  }
17858
17859
  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17860
  // Each interop-var may be specified for at most one action-clause of each
17861
  // interop construct.
17862
0
  llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars;
17863
0
  for (OMPClause *C : Clauses) {
17864
0
    OpenMPClauseKind ClauseKind = C->getClauseKind();
17865
0
    std::pair<ValueDecl *, bool> DeclResult;
17866
0
    SourceLocation ELoc;
17867
0
    SourceRange ERange;
17868
17869
0
    if (ClauseKind == OMPC_init) {
17870
0
      auto *E = cast<OMPInitClause>(C)->getInteropVar();
17871
0
      DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17872
0
    } else if (ClauseKind == OMPC_use) {
17873
0
      auto *E = cast<OMPUseClause>(C)->getInteropVar();
17874
0
      DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17875
0
    } else if (ClauseKind == OMPC_destroy) {
17876
0
      auto *E = cast<OMPDestroyClause>(C)->getInteropVar();
17877
0
      DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17878
0
    }
17879
17880
0
    if (DeclResult.first) {
17881
0
      if (!InteropVars.insert(DeclResult.first).second) {
17882
0
        Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
17883
0
            << DeclResult.first;
17884
0
        return StmtError();
17885
0
      }
17886
0
    }
17887
0
  }
17888
17889
0
  return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
17890
0
}
17891
17892
static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
17893
                                   SourceLocation VarLoc,
17894
0
                                   OpenMPClauseKind Kind) {
17895
0
  SourceLocation ELoc;
17896
0
  SourceRange ERange;
17897
0
  Expr *RefExpr = InteropVarExpr;
17898
0
  auto Res =
17899
0
      getPrivateItem(SemaRef, RefExpr, ELoc, ERange,
17900
0
                     /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
17901
17902
0
  if (Res.second) {
17903
    // It will be analyzed later.
17904
0
    return true;
17905
0
  }
17906
17907
0
  if (!Res.first)
17908
0
    return false;
17909
17910
  // Interop variable should be of type omp_interop_t.
17911
0
  bool HasError = false;
17912
0
  QualType InteropType;
17913
0
  LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
17914
0
                      VarLoc, Sema::LookupOrdinaryName);
17915
0
  if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
17916
0
    NamedDecl *ND = Result.getFoundDecl();
17917
0
    if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
17918
0
      InteropType = QualType(TD->getTypeForDecl(), 0);
17919
0
    } else {
17920
0
      HasError = true;
17921
0
    }
17922
0
  } else {
17923
0
    HasError = true;
17924
0
  }
17925
17926
0
  if (HasError) {
17927
0
    SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
17928
0
        << "omp_interop_t";
17929
0
    return false;
17930
0
  }
17931
17932
0
  QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
17933
0
  if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
17934
0
    SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17935
0
    return false;
17936
0
  }
17937
17938
  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17939
  // The interop-var passed to init or destroy must be non-const.
17940
0
  if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
17941
0
      isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
17942
0
    SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
17943
0
        << /*non-const*/ 1;
17944
0
    return false;
17945
0
  }
17946
0
  return true;
17947
0
}
17948
17949
OMPClause *
17950
Sema::ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
17951
                            SourceLocation StartLoc, SourceLocation LParenLoc,
17952
0
                            SourceLocation VarLoc, SourceLocation EndLoc) {
17953
17954
0
  if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
17955
0
    return nullptr;
17956
17957
  // Check prefer_type values.  These foreign-runtime-id values are either
17958
  // string literals or constant integral expressions.
17959
0
  for (const Expr *E : InteropInfo.PreferTypes) {
17960
0
    if (E->isValueDependent() || E->isTypeDependent() ||
17961
0
        E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
17962
0
      continue;
17963
0
    if (E->isIntegerConstantExpr(Context))
17964
0
      continue;
17965
0
    if (isa<StringLiteral>(E))
17966
0
      continue;
17967
0
    Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
17968
0
    return nullptr;
17969
0
  }
17970
17971
0
  return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc,
17972
0
                               LParenLoc, VarLoc, EndLoc);
17973
0
}
17974
17975
OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
17976
                                      SourceLocation LParenLoc,
17977
                                      SourceLocation VarLoc,
17978
0
                                      SourceLocation EndLoc) {
17979
17980
0
  if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
17981
0
    return nullptr;
17982
17983
0
  return new (Context)
17984
0
      OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17985
0
}
17986
17987
OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
17988
                                          SourceLocation StartLoc,
17989
                                          SourceLocation LParenLoc,
17990
                                          SourceLocation VarLoc,
17991
0
                                          SourceLocation EndLoc) {
17992
0
  if (!InteropVar && LangOpts.OpenMP >= 52 &&
17993
0
      DSAStack->getCurrentDirective() == OMPD_depobj) {
17994
0
    Diag(StartLoc, diag::err_omp_expected_clause_argument)
17995
0
        << getOpenMPClauseName(OMPC_destroy)
17996
0
        << getOpenMPDirectiveName(OMPD_depobj);
17997
0
    return nullptr;
17998
0
  }
17999
0
  if (InteropVar &&
18000
0
      !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
18001
0
    return nullptr;
18002
18003
0
  return new (Context)
18004
0
      OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
18005
0
}
18006
18007
OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
18008
                                             SourceLocation StartLoc,
18009
                                             SourceLocation LParenLoc,
18010
0
                                             SourceLocation EndLoc) {
18011
0
  Expr *ValExpr = Condition;
18012
0
  Stmt *HelperValStmt = nullptr;
18013
0
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18014
0
  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
18015
0
      !Condition->isInstantiationDependent() &&
18016
0
      !Condition->containsUnexpandedParameterPack()) {
18017
0
    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
18018
0
    if (Val.isInvalid())
18019
0
      return nullptr;
18020
18021
0
    ValExpr = MakeFullExpr(Val.get()).get();
18022
18023
0
    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18024
0
    CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
18025
0
                                                    LangOpts.OpenMP);
18026
0
    if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18027
0
      ValExpr = MakeFullExpr(ValExpr).get();
18028
0
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18029
0
      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18030
0
      HelperValStmt = buildPreInits(Context, Captures);
18031
0
    }
18032
0
  }
18033
18034
0
  return new (Context) OMPNovariantsClause(
18035
0
      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18036
0
}
18037
18038
OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
18039
                                            SourceLocation StartLoc,
18040
                                            SourceLocation LParenLoc,
18041
0
                                            SourceLocation EndLoc) {
18042
0
  Expr *ValExpr = Condition;
18043
0
  Stmt *HelperValStmt = nullptr;
18044
0
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18045
0
  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
18046
0
      !Condition->isInstantiationDependent() &&
18047
0
      !Condition->containsUnexpandedParameterPack()) {
18048
0
    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
18049
0
    if (Val.isInvalid())
18050
0
      return nullptr;
18051
18052
0
    ValExpr = MakeFullExpr(Val.get()).get();
18053
18054
0
    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18055
0
    CaptureRegion =
18056
0
        getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
18057
0
    if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18058
0
      ValExpr = MakeFullExpr(ValExpr).get();
18059
0
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18060
0
      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18061
0
      HelperValStmt = buildPreInits(Context, Captures);
18062
0
    }
18063
0
  }
18064
18065
0
  return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
18066
0
                                          StartLoc, LParenLoc, EndLoc);
18067
0
}
18068
18069
OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
18070
                                         SourceLocation StartLoc,
18071
                                         SourceLocation LParenLoc,
18072
0
                                         SourceLocation EndLoc) {
18073
0
  Expr *ValExpr = ThreadID;
18074
0
  Stmt *HelperValStmt = nullptr;
18075
18076
0
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18077
0
  OpenMPDirectiveKind CaptureRegion =
18078
0
      getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
18079
0
  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18080
0
    ValExpr = MakeFullExpr(ValExpr).get();
18081
0
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18082
0
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18083
0
    HelperValStmt = buildPreInits(Context, Captures);
18084
0
  }
18085
18086
0
  return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
18087
0
                                       StartLoc, LParenLoc, EndLoc);
18088
0
}
18089
18090
OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
18091
                                          ArrayRef<Expr *> VarList,
18092
                                          const OMPVarListLocTy &Locs,
18093
0
                                          OpenMPVarListDataTy &Data) {
18094
0
  SourceLocation StartLoc = Locs.StartLoc;
18095
0
  SourceLocation LParenLoc = Locs.LParenLoc;
18096
0
  SourceLocation EndLoc = Locs.EndLoc;
18097
0
  OMPClause *Res = nullptr;
18098
0
  int ExtraModifier = Data.ExtraModifier;
18099
0
  SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
18100
0
  SourceLocation ColonLoc = Data.ColonLoc;
18101
0
  switch (Kind) {
18102
0
  case OMPC_private:
18103
0
    Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18104
0
    break;
18105
0
  case OMPC_firstprivate:
18106
0
    Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18107
0
    break;
18108
0
  case OMPC_lastprivate:
18109
0
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
18110
0
           "Unexpected lastprivate modifier.");
18111
0
    Res = ActOnOpenMPLastprivateClause(
18112
0
        VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
18113
0
        ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
18114
0
    break;
18115
0
  case OMPC_shared:
18116
0
    Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
18117
0
    break;
18118
0
  case OMPC_reduction:
18119
0
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
18120
0
           "Unexpected lastprivate modifier.");
18121
0
    Res = ActOnOpenMPReductionClause(
18122
0
        VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
18123
0
        StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
18124
0
        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18125
0
    break;
18126
0
  case OMPC_task_reduction:
18127
0
    Res = ActOnOpenMPTaskReductionClause(
18128
0
        VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18129
0
        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18130
0
    break;
18131
0
  case OMPC_in_reduction:
18132
0
    Res = ActOnOpenMPInReductionClause(
18133
0
        VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18134
0
        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18135
0
    break;
18136
0
  case OMPC_linear:
18137
0
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
18138
0
           "Unexpected linear modifier.");
18139
0
    Res = ActOnOpenMPLinearClause(
18140
0
        VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
18141
0
        static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
18142
0
        ColonLoc, Data.StepModifierLoc, EndLoc);
18143
0
    break;
18144
0
  case OMPC_aligned:
18145
0
    Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
18146
0
                                   LParenLoc, ColonLoc, EndLoc);
18147
0
    break;
18148
0
  case OMPC_copyin:
18149
0
    Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
18150
0
    break;
18151
0
  case OMPC_copyprivate:
18152
0
    Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18153
0
    break;
18154
0
  case OMPC_flush:
18155
0
    Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
18156
0
    break;
18157
0
  case OMPC_depend:
18158
0
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
18159
0
           "Unexpected depend modifier.");
18160
0
    Res = ActOnOpenMPDependClause(
18161
0
        {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc,
18162
0
         ColonLoc, Data.OmpAllMemoryLoc},
18163
0
        Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
18164
0
    break;
18165
0
  case OMPC_map:
18166
0
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
18167
0
           "Unexpected map modifier.");
18168
0
    Res = ActOnOpenMPMapClause(
18169
0
        Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
18170
0
        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
18171
0
        static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
18172
0
        ExtraModifierLoc, ColonLoc, VarList, Locs);
18173
0
    break;
18174
0
  case OMPC_to:
18175
0
    Res =
18176
0
        ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc,
18177
0
                            Data.ReductionOrMapperIdScopeSpec,
18178
0
                            Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
18179
0
    break;
18180
0
  case OMPC_from:
18181
0
    Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc,
18182
0
                                Data.ReductionOrMapperIdScopeSpec,
18183
0
                                Data.ReductionOrMapperId, ColonLoc, VarList,
18184
0
                                Locs);
18185
0
    break;
18186
0
  case OMPC_use_device_ptr:
18187
0
    Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
18188
0
    break;
18189
0
  case OMPC_use_device_addr:
18190
0
    Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
18191
0
    break;
18192
0
  case OMPC_is_device_ptr:
18193
0
    Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
18194
0
    break;
18195
0
  case OMPC_has_device_addr:
18196
0
    Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
18197
0
    break;
18198
0
  case OMPC_allocate:
18199
0
    Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
18200
0
                                    LParenLoc, ColonLoc, EndLoc);
18201
0
    break;
18202
0
  case OMPC_nontemporal:
18203
0
    Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
18204
0
    break;
18205
0
  case OMPC_inclusive:
18206
0
    Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
18207
0
    break;
18208
0
  case OMPC_exclusive:
18209
0
    Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
18210
0
    break;
18211
0
  case OMPC_affinity:
18212
0
    Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
18213
0
                                    Data.DepModOrTailExpr, VarList);
18214
0
    break;
18215
0
  case OMPC_doacross:
18216
0
    Res = ActOnOpenMPDoacrossClause(
18217
0
        static_cast<OpenMPDoacrossClauseModifier>(ExtraModifier),
18218
0
        ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
18219
0
    break;
18220
0
  case OMPC_if:
18221
0
  case OMPC_depobj:
18222
0
  case OMPC_final:
18223
0
  case OMPC_num_threads:
18224
0
  case OMPC_safelen:
18225
0
  case OMPC_simdlen:
18226
0
  case OMPC_sizes:
18227
0
  case OMPC_allocator:
18228
0
  case OMPC_collapse:
18229
0
  case OMPC_default:
18230
0
  case OMPC_proc_bind:
18231
0
  case OMPC_schedule:
18232
0
  case OMPC_ordered:
18233
0
  case OMPC_nowait:
18234
0
  case OMPC_untied:
18235
0
  case OMPC_mergeable:
18236
0
  case OMPC_threadprivate:
18237
0
  case OMPC_read:
18238
0
  case OMPC_write:
18239
0
  case OMPC_update:
18240
0
  case OMPC_capture:
18241
0
  case OMPC_compare:
18242
0
  case OMPC_seq_cst:
18243
0
  case OMPC_acq_rel:
18244
0
  case OMPC_acquire:
18245
0
  case OMPC_release:
18246
0
  case OMPC_relaxed:
18247
0
  case OMPC_device:
18248
0
  case OMPC_threads:
18249
0
  case OMPC_simd:
18250
0
  case OMPC_num_teams:
18251
0
  case OMPC_thread_limit:
18252
0
  case OMPC_priority:
18253
0
  case OMPC_grainsize:
18254
0
  case OMPC_nogroup:
18255
0
  case OMPC_num_tasks:
18256
0
  case OMPC_hint:
18257
0
  case OMPC_dist_schedule:
18258
0
  case OMPC_defaultmap:
18259
0
  case OMPC_unknown:
18260
0
  case OMPC_uniform:
18261
0
  case OMPC_unified_address:
18262
0
  case OMPC_unified_shared_memory:
18263
0
  case OMPC_reverse_offload:
18264
0
  case OMPC_dynamic_allocators:
18265
0
  case OMPC_atomic_default_mem_order:
18266
0
  case OMPC_device_type:
18267
0
  case OMPC_match:
18268
0
  case OMPC_order:
18269
0
  case OMPC_at:
18270
0
  case OMPC_severity:
18271
0
  case OMPC_message:
18272
0
  case OMPC_destroy:
18273
0
  case OMPC_novariants:
18274
0
  case OMPC_nocontext:
18275
0
  case OMPC_detach:
18276
0
  case OMPC_uses_allocators:
18277
0
  case OMPC_when:
18278
0
  case OMPC_bind:
18279
0
  default:
18280
0
    llvm_unreachable("Clause is not allowed.");
18281
0
  }
18282
0
  return Res;
18283
0
}
18284
18285
ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
18286
0
                                       ExprObjectKind OK, SourceLocation Loc) {
18287
0
  ExprResult Res = BuildDeclRefExpr(
18288
0
      Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
18289
0
  if (!Res.isUsable())
18290
0
    return ExprError();
18291
0
  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
18292
0
    Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
18293
0
    if (!Res.isUsable())
18294
0
      return ExprError();
18295
0
  }
18296
0
  if (VK != VK_LValue && Res.get()->isGLValue()) {
18297
0
    Res = DefaultLvalueConversion(Res.get());
18298
0
    if (!Res.isUsable())
18299
0
      return ExprError();
18300
0
  }
18301
0
  return Res;
18302
0
}
18303
18304
OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
18305
                                          SourceLocation StartLoc,
18306
                                          SourceLocation LParenLoc,
18307
0
                                          SourceLocation EndLoc) {
18308
0
  SmallVector<Expr *, 8> Vars;
18309
0
  SmallVector<Expr *, 8> PrivateCopies;
18310
0
  bool IsImplicitClause =
18311
0
      StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18312
0
  for (Expr *RefExpr : VarList) {
18313
0
    assert(RefExpr && "NULL expr in OpenMP private clause.");
18314
0
    SourceLocation ELoc;
18315
0
    SourceRange ERange;
18316
0
    Expr *SimpleRefExpr = RefExpr;
18317
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18318
0
    if (Res.second) {
18319
      // It will be analyzed later.
18320
0
      Vars.push_back(RefExpr);
18321
0
      PrivateCopies.push_back(nullptr);
18322
0
    }
18323
0
    ValueDecl *D = Res.first;
18324
0
    if (!D)
18325
0
      continue;
18326
18327
0
    QualType Type = D->getType();
18328
0
    auto *VD = dyn_cast<VarDecl>(D);
18329
18330
    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18331
    //  A variable that appears in a private clause must not have an incomplete
18332
    //  type or a reference type.
18333
0
    if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
18334
0
      continue;
18335
0
    Type = Type.getNonReferenceType();
18336
18337
    // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18338
    // A variable that is privatized must not have a const-qualified type
18339
    // unless it is of class type with a mutable member. This restriction does
18340
    // not apply to the firstprivate clause.
18341
    //
18342
    // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
18343
    // A variable that appears in a private clause must not have a
18344
    // const-qualified type unless it is of class type with a mutable member.
18345
0
    if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
18346
0
      continue;
18347
18348
    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18349
    // in a Construct]
18350
    //  Variables with the predetermined data-sharing attributes may not be
18351
    //  listed in data-sharing attributes clauses, except for the cases
18352
    //  listed below. For these exceptions only, listing a predetermined
18353
    //  variable in a data-sharing attribute clause is allowed and overrides
18354
    //  the variable's predetermined data-sharing attributes.
18355
0
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18356
0
    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
18357
0
      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18358
0
                                          << getOpenMPClauseName(OMPC_private);
18359
0
      reportOriginalDsa(*this, DSAStack, D, DVar);
18360
0
      continue;
18361
0
    }
18362
18363
0
    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18364
    // Variably modified types are not supported for tasks.
18365
0
    if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18366
0
        isOpenMPTaskingDirective(CurrDir)) {
18367
0
      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18368
0
          << getOpenMPClauseName(OMPC_private) << Type
18369
0
          << getOpenMPDirectiveName(CurrDir);
18370
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18371
0
                               VarDecl::DeclarationOnly;
18372
0
      Diag(D->getLocation(),
18373
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18374
0
          << D;
18375
0
      continue;
18376
0
    }
18377
18378
    // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18379
    // A list item cannot appear in both a map clause and a data-sharing
18380
    // attribute clause on the same construct
18381
    //
18382
    // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18383
    // A list item cannot appear in both a map clause and a data-sharing
18384
    // attribute clause on the same construct unless the construct is a
18385
    // combined construct.
18386
0
    if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
18387
0
        CurrDir == OMPD_target) {
18388
0
      OpenMPClauseKind ConflictKind;
18389
0
      if (DSAStack->checkMappableExprComponentListsForDecl(
18390
0
              VD, /*CurrentRegionOnly=*/true,
18391
0
              [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
18392
0
                  OpenMPClauseKind WhereFoundClauseKind) -> bool {
18393
0
                ConflictKind = WhereFoundClauseKind;
18394
0
                return true;
18395
0
              })) {
18396
0
        Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18397
0
            << getOpenMPClauseName(OMPC_private)
18398
0
            << getOpenMPClauseName(ConflictKind)
18399
0
            << getOpenMPDirectiveName(CurrDir);
18400
0
        reportOriginalDsa(*this, DSAStack, D, DVar);
18401
0
        continue;
18402
0
      }
18403
0
    }
18404
18405
    // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
18406
    //  A variable of class type (or array thereof) that appears in a private
18407
    //  clause requires an accessible, unambiguous default constructor for the
18408
    //  class type.
18409
    // Generate helper private variable and initialize it with the default
18410
    // value. The address of the original variable is replaced by the address of
18411
    // the new private variable in CodeGen. This new variable is not added to
18412
    // IdResolver, so the code in the OpenMP region uses original variable for
18413
    // proper diagnostics.
18414
0
    Type = Type.getUnqualifiedType();
18415
0
    VarDecl *VDPrivate =
18416
0
        buildVarDecl(*this, ELoc, Type, D->getName(),
18417
0
                     D->hasAttrs() ? &D->getAttrs() : nullptr,
18418
0
                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18419
0
    ActOnUninitializedDecl(VDPrivate);
18420
0
    if (VDPrivate->isInvalidDecl())
18421
0
      continue;
18422
0
    DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18423
0
        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18424
18425
0
    DeclRefExpr *Ref = nullptr;
18426
0
    if (!VD && !CurContext->isDependentContext()) {
18427
0
      auto *FD = dyn_cast<FieldDecl>(D);
18428
0
      VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18429
0
      if (VD)
18430
0
        Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18431
0
                               RefExpr->getExprLoc());
18432
0
      else
18433
0
        Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18434
0
    }
18435
0
    if (!IsImplicitClause)
18436
0
      DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18437
0
    Vars.push_back((VD || CurContext->isDependentContext())
18438
0
                       ? RefExpr->IgnoreParens()
18439
0
                       : Ref);
18440
0
    PrivateCopies.push_back(VDPrivateRefExpr);
18441
0
  }
18442
18443
0
  if (Vars.empty())
18444
0
    return nullptr;
18445
18446
0
  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
18447
0
                                  PrivateCopies);
18448
0
}
18449
18450
OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
18451
                                               SourceLocation StartLoc,
18452
                                               SourceLocation LParenLoc,
18453
0
                                               SourceLocation EndLoc) {
18454
0
  SmallVector<Expr *, 8> Vars;
18455
0
  SmallVector<Expr *, 8> PrivateCopies;
18456
0
  SmallVector<Expr *, 8> Inits;
18457
0
  SmallVector<Decl *, 4> ExprCaptures;
18458
0
  bool IsImplicitClause =
18459
0
      StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18460
0
  SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
18461
18462
0
  for (Expr *RefExpr : VarList) {
18463
0
    assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
18464
0
    SourceLocation ELoc;
18465
0
    SourceRange ERange;
18466
0
    Expr *SimpleRefExpr = RefExpr;
18467
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18468
0
    if (Res.second) {
18469
      // It will be analyzed later.
18470
0
      Vars.push_back(RefExpr);
18471
0
      PrivateCopies.push_back(nullptr);
18472
0
      Inits.push_back(nullptr);
18473
0
    }
18474
0
    ValueDecl *D = Res.first;
18475
0
    if (!D)
18476
0
      continue;
18477
18478
0
    ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
18479
0
    QualType Type = D->getType();
18480
0
    auto *VD = dyn_cast<VarDecl>(D);
18481
18482
    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18483
    //  A variable that appears in a private clause must not have an incomplete
18484
    //  type or a reference type.
18485
0
    if (RequireCompleteType(ELoc, Type,
18486
0
                            diag::err_omp_firstprivate_incomplete_type))
18487
0
      continue;
18488
0
    Type = Type.getNonReferenceType();
18489
18490
    // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
18491
    //  A variable of class type (or array thereof) that appears in a private
18492
    //  clause requires an accessible, unambiguous copy constructor for the
18493
    //  class type.
18494
0
    QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
18495
18496
    // If an implicit firstprivate variable found it was checked already.
18497
0
    DSAStackTy::DSAVarData TopDVar;
18498
0
    if (!IsImplicitClause) {
18499
0
      DSAStackTy::DSAVarData DVar =
18500
0
          DSAStack->getTopDSA(D, /*FromParent=*/false);
18501
0
      TopDVar = DVar;
18502
0
      OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18503
0
      bool IsConstant = ElemType.isConstant(Context);
18504
      // OpenMP [2.4.13, Data-sharing Attribute Clauses]
18505
      //  A list item that specifies a given variable may not appear in more
18506
      // than one clause on the same directive, except that a variable may be
18507
      //  specified in both firstprivate and lastprivate clauses.
18508
      // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18509
      // A list item may appear in a firstprivate or lastprivate clause but not
18510
      // both.
18511
0
      if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18512
0
          (isOpenMPDistributeDirective(CurrDir) ||
18513
0
           DVar.CKind != OMPC_lastprivate) &&
18514
0
          DVar.RefExpr) {
18515
0
        Diag(ELoc, diag::err_omp_wrong_dsa)
18516
0
            << getOpenMPClauseName(DVar.CKind)
18517
0
            << getOpenMPClauseName(OMPC_firstprivate);
18518
0
        reportOriginalDsa(*this, DSAStack, D, DVar);
18519
0
        continue;
18520
0
      }
18521
18522
      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18523
      // in a Construct]
18524
      //  Variables with the predetermined data-sharing attributes may not be
18525
      //  listed in data-sharing attributes clauses, except for the cases
18526
      //  listed below. For these exceptions only, listing a predetermined
18527
      //  variable in a data-sharing attribute clause is allowed and overrides
18528
      //  the variable's predetermined data-sharing attributes.
18529
      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18530
      // in a Construct, C/C++, p.2]
18531
      //  Variables with const-qualified type having no mutable member may be
18532
      //  listed in a firstprivate clause, even if they are static data members.
18533
0
      if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
18534
0
          DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
18535
0
        Diag(ELoc, diag::err_omp_wrong_dsa)
18536
0
            << getOpenMPClauseName(DVar.CKind)
18537
0
            << getOpenMPClauseName(OMPC_firstprivate);
18538
0
        reportOriginalDsa(*this, DSAStack, D, DVar);
18539
0
        continue;
18540
0
      }
18541
18542
      // OpenMP [2.9.3.4, Restrictions, p.2]
18543
      //  A list item that is private within a parallel region must not appear
18544
      //  in a firstprivate clause on a worksharing construct if any of the
18545
      //  worksharing regions arising from the worksharing construct ever bind
18546
      //  to any of the parallel regions arising from the parallel construct.
18547
      // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18548
      // A list item that is private within a teams region must not appear in a
18549
      // firstprivate clause on a distribute construct if any of the distribute
18550
      // regions arising from the distribute construct ever bind to any of the
18551
      // teams regions arising from the teams construct.
18552
      // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18553
      // A list item that appears in a reduction clause of a teams construct
18554
      // must not appear in a firstprivate clause on a distribute construct if
18555
      // any of the distribute regions arising from the distribute construct
18556
      // ever bind to any of the teams regions arising from the teams construct.
18557
0
      if ((isOpenMPWorksharingDirective(CurrDir) ||
18558
0
           isOpenMPDistributeDirective(CurrDir)) &&
18559
0
          !isOpenMPParallelDirective(CurrDir) &&
18560
0
          !isOpenMPTeamsDirective(CurrDir)) {
18561
0
        DVar = DSAStack->getImplicitDSA(D, true);
18562
0
        if (DVar.CKind != OMPC_shared &&
18563
0
            (isOpenMPParallelDirective(DVar.DKind) ||
18564
0
             isOpenMPTeamsDirective(DVar.DKind) ||
18565
0
             DVar.DKind == OMPD_unknown)) {
18566
0
          Diag(ELoc, diag::err_omp_required_access)
18567
0
              << getOpenMPClauseName(OMPC_firstprivate)
18568
0
              << getOpenMPClauseName(OMPC_shared);
18569
0
          reportOriginalDsa(*this, DSAStack, D, DVar);
18570
0
          continue;
18571
0
        }
18572
0
      }
18573
      // OpenMP [2.9.3.4, Restrictions, p.3]
18574
      //  A list item that appears in a reduction clause of a parallel construct
18575
      //  must not appear in a firstprivate clause on a worksharing or task
18576
      //  construct if any of the worksharing or task regions arising from the
18577
      //  worksharing or task construct ever bind to any of the parallel regions
18578
      //  arising from the parallel construct.
18579
      // OpenMP [2.9.3.4, Restrictions, p.4]
18580
      //  A list item that appears in a reduction clause in worksharing
18581
      //  construct must not appear in a firstprivate clause in a task construct
18582
      //  encountered during execution of any of the worksharing regions arising
18583
      //  from the worksharing construct.
18584
0
      if (isOpenMPTaskingDirective(CurrDir)) {
18585
0
        DVar = DSAStack->hasInnermostDSA(
18586
0
            D,
18587
0
            [](OpenMPClauseKind C, bool AppliedToPointee) {
18588
0
              return C == OMPC_reduction && !AppliedToPointee;
18589
0
            },
18590
0
            [](OpenMPDirectiveKind K) {
18591
0
              return isOpenMPParallelDirective(K) ||
18592
0
                     isOpenMPWorksharingDirective(K) ||
18593
0
                     isOpenMPTeamsDirective(K);
18594
0
            },
18595
0
            /*FromParent=*/true);
18596
0
        if (DVar.CKind == OMPC_reduction &&
18597
0
            (isOpenMPParallelDirective(DVar.DKind) ||
18598
0
             isOpenMPWorksharingDirective(DVar.DKind) ||
18599
0
             isOpenMPTeamsDirective(DVar.DKind))) {
18600
0
          Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18601
0
              << getOpenMPDirectiveName(DVar.DKind);
18602
0
          reportOriginalDsa(*this, DSAStack, D, DVar);
18603
0
          continue;
18604
0
        }
18605
0
      }
18606
18607
      // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18608
      // A list item cannot appear in both a map clause and a data-sharing
18609
      // attribute clause on the same construct
18610
      //
18611
      // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18612
      // A list item cannot appear in both a map clause and a data-sharing
18613
      // attribute clause on the same construct unless the construct is a
18614
      // combined construct.
18615
0
      if ((LangOpts.OpenMP <= 45 &&
18616
0
           isOpenMPTargetExecutionDirective(CurrDir)) ||
18617
0
          CurrDir == OMPD_target) {
18618
0
        OpenMPClauseKind ConflictKind;
18619
0
        if (DSAStack->checkMappableExprComponentListsForDecl(
18620
0
                VD, /*CurrentRegionOnly=*/true,
18621
0
                [&ConflictKind](
18622
0
                    OMPClauseMappableExprCommon::MappableExprComponentListRef,
18623
0
                    OpenMPClauseKind WhereFoundClauseKind) {
18624
0
                  ConflictKind = WhereFoundClauseKind;
18625
0
                  return true;
18626
0
                })) {
18627
0
          Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18628
0
              << getOpenMPClauseName(OMPC_firstprivate)
18629
0
              << getOpenMPClauseName(ConflictKind)
18630
0
              << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18631
0
          reportOriginalDsa(*this, DSAStack, D, DVar);
18632
0
          continue;
18633
0
        }
18634
0
      }
18635
0
    }
18636
18637
    // Variably modified types are not supported for tasks.
18638
0
    if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18639
0
        isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
18640
0
      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18641
0
          << getOpenMPClauseName(OMPC_firstprivate) << Type
18642
0
          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18643
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18644
0
                               VarDecl::DeclarationOnly;
18645
0
      Diag(D->getLocation(),
18646
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18647
0
          << D;
18648
0
      continue;
18649
0
    }
18650
18651
0
    Type = Type.getUnqualifiedType();
18652
0
    VarDecl *VDPrivate =
18653
0
        buildVarDecl(*this, ELoc, Type, D->getName(),
18654
0
                     D->hasAttrs() ? &D->getAttrs() : nullptr,
18655
0
                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18656
    // Generate helper private variable and initialize it with the value of the
18657
    // original variable. The address of the original variable is replaced by
18658
    // the address of the new private variable in the CodeGen. This new variable
18659
    // is not added to IdResolver, so the code in the OpenMP region uses
18660
    // original variable for proper diagnostics and variable capturing.
18661
0
    Expr *VDInitRefExpr = nullptr;
18662
    // For arrays generate initializer for single element and replace it by the
18663
    // original array element in CodeGen.
18664
0
    if (Type->isArrayType()) {
18665
0
      VarDecl *VDInit =
18666
0
          buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
18667
0
      VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
18668
0
      Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
18669
0
      ElemType = ElemType.getUnqualifiedType();
18670
0
      VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
18671
0
                                         ".firstprivate.temp");
18672
0
      InitializedEntity Entity =
18673
0
          InitializedEntity::InitializeVariable(VDInitTemp);
18674
0
      InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
18675
18676
0
      InitializationSequence InitSeq(*this, Entity, Kind, Init);
18677
0
      ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
18678
0
      if (Result.isInvalid())
18679
0
        VDPrivate->setInvalidDecl();
18680
0
      else
18681
0
        VDPrivate->setInit(Result.getAs<Expr>());
18682
      // Remove temp variable declaration.
18683
0
      Context.Deallocate(VDInitTemp);
18684
0
    } else {
18685
0
      VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
18686
0
                                     ".firstprivate.temp");
18687
0
      VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
18688
0
                                       RefExpr->getExprLoc());
18689
0
      AddInitializerToDecl(VDPrivate,
18690
0
                           DefaultLvalueConversion(VDInitRefExpr).get(),
18691
0
                           /*DirectInit=*/false);
18692
0
    }
18693
0
    if (VDPrivate->isInvalidDecl()) {
18694
0
      if (IsImplicitClause) {
18695
0
        Diag(RefExpr->getExprLoc(),
18696
0
             diag::note_omp_task_predetermined_firstprivate_here);
18697
0
      }
18698
0
      continue;
18699
0
    }
18700
0
    CurContext->addDecl(VDPrivate);
18701
0
    DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18702
0
        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
18703
0
        RefExpr->getExprLoc());
18704
0
    DeclRefExpr *Ref = nullptr;
18705
0
    if (!VD && !CurContext->isDependentContext()) {
18706
0
      if (TopDVar.CKind == OMPC_lastprivate) {
18707
0
        Ref = TopDVar.PrivateCopy;
18708
0
      } else {
18709
0
        auto *FD = dyn_cast<FieldDecl>(D);
18710
0
        VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18711
0
        if (VD)
18712
0
          Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18713
0
                                 RefExpr->getExprLoc());
18714
0
        else
18715
0
          Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18716
0
        if (VD || !isOpenMPCapturedDecl(D))
18717
0
          ExprCaptures.push_back(Ref->getDecl());
18718
0
      }
18719
0
    }
18720
0
    if (!IsImplicitClause)
18721
0
      DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18722
0
    Vars.push_back((VD || CurContext->isDependentContext())
18723
0
                       ? RefExpr->IgnoreParens()
18724
0
                       : Ref);
18725
0
    PrivateCopies.push_back(VDPrivateRefExpr);
18726
0
    Inits.push_back(VDInitRefExpr);
18727
0
  }
18728
18729
0
  if (Vars.empty())
18730
0
    return nullptr;
18731
18732
0
  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18733
0
                                       Vars, PrivateCopies, Inits,
18734
0
                                       buildPreInits(Context, ExprCaptures));
18735
0
}
18736
18737
OMPClause *Sema::ActOnOpenMPLastprivateClause(
18738
    ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
18739
    SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
18740
0
    SourceLocation LParenLoc, SourceLocation EndLoc) {
18741
0
  if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
18742
0
    assert(ColonLoc.isValid() && "Colon location must be valid.");
18743
0
    Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18744
0
        << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
18745
0
                                   /*Last=*/OMPC_LASTPRIVATE_unknown)
18746
0
        << getOpenMPClauseName(OMPC_lastprivate);
18747
0
    return nullptr;
18748
0
  }
18749
18750
0
  SmallVector<Expr *, 8> Vars;
18751
0
  SmallVector<Expr *, 8> SrcExprs;
18752
0
  SmallVector<Expr *, 8> DstExprs;
18753
0
  SmallVector<Expr *, 8> AssignmentOps;
18754
0
  SmallVector<Decl *, 4> ExprCaptures;
18755
0
  SmallVector<Expr *, 4> ExprPostUpdates;
18756
0
  for (Expr *RefExpr : VarList) {
18757
0
    assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18758
0
    SourceLocation ELoc;
18759
0
    SourceRange ERange;
18760
0
    Expr *SimpleRefExpr = RefExpr;
18761
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18762
0
    if (Res.second) {
18763
      // It will be analyzed later.
18764
0
      Vars.push_back(RefExpr);
18765
0
      SrcExprs.push_back(nullptr);
18766
0
      DstExprs.push_back(nullptr);
18767
0
      AssignmentOps.push_back(nullptr);
18768
0
    }
18769
0
    ValueDecl *D = Res.first;
18770
0
    if (!D)
18771
0
      continue;
18772
18773
0
    QualType Type = D->getType();
18774
0
    auto *VD = dyn_cast<VarDecl>(D);
18775
18776
    // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
18777
    //  A variable that appears in a lastprivate clause must not have an
18778
    //  incomplete type or a reference type.
18779
0
    if (RequireCompleteType(ELoc, Type,
18780
0
                            diag::err_omp_lastprivate_incomplete_type))
18781
0
      continue;
18782
0
    Type = Type.getNonReferenceType();
18783
18784
    // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18785
    // A variable that is privatized must not have a const-qualified type
18786
    // unless it is of class type with a mutable member. This restriction does
18787
    // not apply to the firstprivate clause.
18788
    //
18789
    // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
18790
    // A variable that appears in a lastprivate clause must not have a
18791
    // const-qualified type unless it is of class type with a mutable member.
18792
0
    if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
18793
0
      continue;
18794
18795
    // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
18796
    // A list item that appears in a lastprivate clause with the conditional
18797
    // modifier must be a scalar variable.
18798
0
    if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
18799
0
      Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18800
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18801
0
                               VarDecl::DeclarationOnly;
18802
0
      Diag(D->getLocation(),
18803
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18804
0
          << D;
18805
0
      continue;
18806
0
    }
18807
18808
0
    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18809
    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18810
    // in a Construct]
18811
    //  Variables with the predetermined data-sharing attributes may not be
18812
    //  listed in data-sharing attributes clauses, except for the cases
18813
    //  listed below.
18814
    // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18815
    // A list item may appear in a firstprivate or lastprivate clause but not
18816
    // both.
18817
0
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18818
0
    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
18819
0
        (isOpenMPDistributeDirective(CurrDir) ||
18820
0
         DVar.CKind != OMPC_firstprivate) &&
18821
0
        (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
18822
0
      Diag(ELoc, diag::err_omp_wrong_dsa)
18823
0
          << getOpenMPClauseName(DVar.CKind)
18824
0
          << getOpenMPClauseName(OMPC_lastprivate);
18825
0
      reportOriginalDsa(*this, DSAStack, D, DVar);
18826
0
      continue;
18827
0
    }
18828
18829
    // OpenMP [2.14.3.5, Restrictions, p.2]
18830
    // A list item that is private within a parallel region, or that appears in
18831
    // the reduction clause of a parallel construct, must not appear in a
18832
    // lastprivate clause on a worksharing construct if any of the corresponding
18833
    // worksharing regions ever binds to any of the corresponding parallel
18834
    // regions.
18835
0
    DSAStackTy::DSAVarData TopDVar = DVar;
18836
0
    if (isOpenMPWorksharingDirective(CurrDir) &&
18837
0
        !isOpenMPParallelDirective(CurrDir) &&
18838
0
        !isOpenMPTeamsDirective(CurrDir)) {
18839
0
      DVar = DSAStack->getImplicitDSA(D, true);
18840
0
      if (DVar.CKind != OMPC_shared) {
18841
0
        Diag(ELoc, diag::err_omp_required_access)
18842
0
            << getOpenMPClauseName(OMPC_lastprivate)
18843
0
            << getOpenMPClauseName(OMPC_shared);
18844
0
        reportOriginalDsa(*this, DSAStack, D, DVar);
18845
0
        continue;
18846
0
      }
18847
0
    }
18848
18849
    // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
18850
    //  A variable of class type (or array thereof) that appears in a
18851
    //  lastprivate clause requires an accessible, unambiguous default
18852
    //  constructor for the class type, unless the list item is also specified
18853
    //  in a firstprivate clause.
18854
    //  A variable of class type (or array thereof) that appears in a
18855
    //  lastprivate clause requires an accessible, unambiguous copy assignment
18856
    //  operator for the class type.
18857
0
    Type = Context.getBaseElementType(Type).getNonReferenceType();
18858
0
    VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
18859
0
                                  Type.getUnqualifiedType(), ".lastprivate.src",
18860
0
                                  D->hasAttrs() ? &D->getAttrs() : nullptr);
18861
0
    DeclRefExpr *PseudoSrcExpr =
18862
0
        buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
18863
0
    VarDecl *DstVD =
18864
0
        buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
18865
0
                     D->hasAttrs() ? &D->getAttrs() : nullptr);
18866
0
    DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18867
    // For arrays generate assignment operation for single element and replace
18868
    // it by the original array element in CodeGen.
18869
0
    ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
18870
0
                                         PseudoDstExpr, PseudoSrcExpr);
18871
0
    if (AssignmentOp.isInvalid())
18872
0
      continue;
18873
0
    AssignmentOp =
18874
0
        ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18875
0
    if (AssignmentOp.isInvalid())
18876
0
      continue;
18877
18878
0
    DeclRefExpr *Ref = nullptr;
18879
0
    if (!VD && !CurContext->isDependentContext()) {
18880
0
      if (TopDVar.CKind == OMPC_firstprivate) {
18881
0
        Ref = TopDVar.PrivateCopy;
18882
0
      } else {
18883
0
        Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18884
0
        if (!isOpenMPCapturedDecl(D))
18885
0
          ExprCaptures.push_back(Ref->getDecl());
18886
0
      }
18887
0
      if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
18888
0
          (!isOpenMPCapturedDecl(D) &&
18889
0
           Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
18890
0
        ExprResult RefRes = DefaultLvalueConversion(Ref);
18891
0
        if (!RefRes.isUsable())
18892
0
          continue;
18893
0
        ExprResult PostUpdateRes =
18894
0
            BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18895
0
                       RefRes.get());
18896
0
        if (!PostUpdateRes.isUsable())
18897
0
          continue;
18898
0
        ExprPostUpdates.push_back(
18899
0
            IgnoredValueConversions(PostUpdateRes.get()).get());
18900
0
      }
18901
0
    }
18902
0
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18903
0
    Vars.push_back((VD || CurContext->isDependentContext())
18904
0
                       ? RefExpr->IgnoreParens()
18905
0
                       : Ref);
18906
0
    SrcExprs.push_back(PseudoSrcExpr);
18907
0
    DstExprs.push_back(PseudoDstExpr);
18908
0
    AssignmentOps.push_back(AssignmentOp.get());
18909
0
  }
18910
18911
0
  if (Vars.empty())
18912
0
    return nullptr;
18913
18914
0
  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18915
0
                                      Vars, SrcExprs, DstExprs, AssignmentOps,
18916
0
                                      LPKind, LPKindLoc, ColonLoc,
18917
0
                                      buildPreInits(Context, ExprCaptures),
18918
0
                                      buildPostUpdate(*this, ExprPostUpdates));
18919
0
}
18920
18921
OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
18922
                                         SourceLocation StartLoc,
18923
                                         SourceLocation LParenLoc,
18924
0
                                         SourceLocation EndLoc) {
18925
0
  SmallVector<Expr *, 8> Vars;
18926
0
  for (Expr *RefExpr : VarList) {
18927
0
    assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18928
0
    SourceLocation ELoc;
18929
0
    SourceRange ERange;
18930
0
    Expr *SimpleRefExpr = RefExpr;
18931
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18932
0
    if (Res.second) {
18933
      // It will be analyzed later.
18934
0
      Vars.push_back(RefExpr);
18935
0
    }
18936
0
    ValueDecl *D = Res.first;
18937
0
    if (!D)
18938
0
      continue;
18939
18940
0
    auto *VD = dyn_cast<VarDecl>(D);
18941
    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18942
    // in a Construct]
18943
    //  Variables with the predetermined data-sharing attributes may not be
18944
    //  listed in data-sharing attributes clauses, except for the cases
18945
    //  listed below. For these exceptions only, listing a predetermined
18946
    //  variable in a data-sharing attribute clause is allowed and overrides
18947
    //  the variable's predetermined data-sharing attributes.
18948
0
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18949
0
    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
18950
0
        DVar.RefExpr) {
18951
0
      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18952
0
                                          << getOpenMPClauseName(OMPC_shared);
18953
0
      reportOriginalDsa(*this, DSAStack, D, DVar);
18954
0
      continue;
18955
0
    }
18956
18957
0
    DeclRefExpr *Ref = nullptr;
18958
0
    if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
18959
0
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18960
0
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18961
0
    Vars.push_back((VD || !Ref || CurContext->isDependentContext())
18962
0
                       ? RefExpr->IgnoreParens()
18963
0
                       : Ref);
18964
0
  }
18965
18966
0
  if (Vars.empty())
18967
0
    return nullptr;
18968
18969
0
  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18970
0
}
18971
18972
namespace {
18973
class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
18974
  DSAStackTy *Stack;
18975
18976
public:
18977
0
  bool VisitDeclRefExpr(DeclRefExpr *E) {
18978
0
    if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
18979
0
      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
18980
0
      if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
18981
0
        return false;
18982
0
      if (DVar.CKind != OMPC_unknown)
18983
0
        return true;
18984
0
      DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
18985
0
          VD,
18986
0
          [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
18987
0
            return isOpenMPPrivate(C) && !AppliedToPointee;
18988
0
          },
18989
0
          [](OpenMPDirectiveKind) { return true; },
18990
0
          /*FromParent=*/true);
18991
0
      return DVarPrivate.CKind != OMPC_unknown;
18992
0
    }
18993
0
    return false;
18994
0
  }
18995
0
  bool VisitStmt(Stmt *S) {
18996
0
    for (Stmt *Child : S->children()) {
18997
0
      if (Child && Visit(Child))
18998
0
        return true;
18999
0
    }
19000
0
    return false;
19001
0
  }
19002
0
  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
19003
};
19004
} // namespace
19005
19006
namespace {
19007
// Transform MemberExpression for specified FieldDecl of current class to
19008
// DeclRefExpr to specified OMPCapturedExprDecl.
19009
class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
19010
  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
19011
  ValueDecl *Field = nullptr;
19012
  DeclRefExpr *CapturedExpr = nullptr;
19013
19014
public:
19015
  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
19016
0
      : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
19017
19018
0
  ExprResult TransformMemberExpr(MemberExpr *E) {
19019
0
    if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
19020
0
        E->getMemberDecl() == Field) {
19021
0
      CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
19022
0
      return CapturedExpr;
19023
0
    }
19024
0
    return BaseTransform::TransformMemberExpr(E);
19025
0
  }
19026
0
  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
19027
};
19028
} // namespace
19029
19030
template <typename T, typename U>
19031
static T filterLookupForUDReductionAndMapper(
19032
0
    SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
19033
0
  for (U &Set : Lookups) {
19034
0
    for (auto *D : Set) {
19035
0
      if (T Res = Gen(cast<ValueDecl>(D)))
19036
0
        return Res;
19037
0
    }
19038
0
  }
19039
0
  return T();
19040
0
}
Unexecuted instantiation: SemaOpenMP.cpp:bool filterLookupForUDReductionAndMapper<bool, clang::UnresolvedSet<8u> >(llvm::SmallVectorImpl<clang::UnresolvedSet<8u> >&, llvm::function_ref<bool (clang::ValueDecl*)>)
Unexecuted instantiation: SemaOpenMP.cpp:clang::ValueDecl* filterLookupForUDReductionAndMapper<clang::ValueDecl*, clang::UnresolvedSet<8u> >(llvm::SmallVectorImpl<clang::UnresolvedSet<8u> >&, llvm::function_ref<clang::ValueDecl* (clang::ValueDecl*)>)
19041
19042
0
static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
19043
0
  assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
19044
19045
0
  for (auto *RD : D->redecls()) {
19046
    // Don't bother with extra checks if we already know this one isn't visible.
19047
0
    if (RD == D)
19048
0
      continue;
19049
19050
0
    auto ND = cast<NamedDecl>(RD);
19051
0
    if (LookupResult::isVisible(SemaRef, ND))
19052
0
      return ND;
19053
0
  }
19054
19055
0
  return nullptr;
19056
0
}
19057
19058
static void
19059
argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
19060
                        SourceLocation Loc, QualType Ty,
19061
0
                        SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
19062
  // Find all of the associated namespaces and classes based on the
19063
  // arguments we have.
19064
0
  Sema::AssociatedNamespaceSet AssociatedNamespaces;
19065
0
  Sema::AssociatedClassSet AssociatedClasses;
19066
0
  OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
19067
0
  SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
19068
0
                                             AssociatedClasses);
19069
19070
  // C++ [basic.lookup.argdep]p3:
19071
  //   Let X be the lookup set produced by unqualified lookup (3.4.1)
19072
  //   and let Y be the lookup set produced by argument dependent
19073
  //   lookup (defined as follows). If X contains [...] then Y is
19074
  //   empty. Otherwise Y is the set of declarations found in the
19075
  //   namespaces associated with the argument types as described
19076
  //   below. The set of declarations found by the lookup of the name
19077
  //   is the union of X and Y.
19078
  //
19079
  // Here, we compute Y and add its members to the overloaded
19080
  // candidate set.
19081
0
  for (auto *NS : AssociatedNamespaces) {
19082
    //   When considering an associated namespace, the lookup is the
19083
    //   same as the lookup performed when the associated namespace is
19084
    //   used as a qualifier (3.4.3.2) except that:
19085
    //
19086
    //     -- Any using-directives in the associated namespace are
19087
    //        ignored.
19088
    //
19089
    //     -- Any namespace-scope friend functions declared in
19090
    //        associated classes are visible within their respective
19091
    //        namespaces even if they are not visible during an ordinary
19092
    //        lookup (11.4).
19093
0
    DeclContext::lookup_result R = NS->lookup(Id.getName());
19094
0
    for (auto *D : R) {
19095
0
      auto *Underlying = D;
19096
0
      if (auto *USD = dyn_cast<UsingShadowDecl>(D))
19097
0
        Underlying = USD->getTargetDecl();
19098
19099
0
      if (!isa<OMPDeclareReductionDecl>(Underlying) &&
19100
0
          !isa<OMPDeclareMapperDecl>(Underlying))
19101
0
        continue;
19102
19103
0
      if (!SemaRef.isVisible(D)) {
19104
0
        D = findAcceptableDecl(SemaRef, D);
19105
0
        if (!D)
19106
0
          continue;
19107
0
        if (auto *USD = dyn_cast<UsingShadowDecl>(D))
19108
0
          Underlying = USD->getTargetDecl();
19109
0
      }
19110
0
      Lookups.emplace_back();
19111
0
      Lookups.back().addDecl(Underlying);
19112
0
    }
19113
0
  }
19114
0
}
19115
19116
static ExprResult
19117
buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
19118
                         Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
19119
                         const DeclarationNameInfo &ReductionId, QualType Ty,
19120
0
                         CXXCastPath &BasePath, Expr *UnresolvedReduction) {
19121
0
  if (ReductionIdScopeSpec.isInvalid())
19122
0
    return ExprError();
19123
0
  SmallVector<UnresolvedSet<8>, 4> Lookups;
19124
0
  if (S) {
19125
0
    LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
19126
0
    Lookup.suppressDiagnostics();
19127
0
    while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
19128
0
      NamedDecl *D = Lookup.getRepresentativeDecl();
19129
0
      do {
19130
0
        S = S->getParent();
19131
0
      } while (S && !S->isDeclScope(D));
19132
0
      if (S)
19133
0
        S = S->getParent();
19134
0
      Lookups.emplace_back();
19135
0
      Lookups.back().append(Lookup.begin(), Lookup.end());
19136
0
      Lookup.clear();
19137
0
    }
19138
0
  } else if (auto *ULE =
19139
0
                 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
19140
0
    Lookups.push_back(UnresolvedSet<8>());
19141
0
    Decl *PrevD = nullptr;
19142
0
    for (NamedDecl *D : ULE->decls()) {
19143
0
      if (D == PrevD)
19144
0
        Lookups.push_back(UnresolvedSet<8>());
19145
0
      else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
19146
0
        Lookups.back().addDecl(DRD);
19147
0
      PrevD = D;
19148
0
    }
19149
0
  }
19150
0
  if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
19151
0
      Ty->isInstantiationDependentType() ||
19152
0
      Ty->containsUnexpandedParameterPack() ||
19153
0
      filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
19154
0
        return !D->isInvalidDecl() &&
19155
0
               (D->getType()->isDependentType() ||
19156
0
                D->getType()->isInstantiationDependentType() ||
19157
0
                D->getType()->containsUnexpandedParameterPack());
19158
0
      })) {
19159
0
    UnresolvedSet<8> ResSet;
19160
0
    for (const UnresolvedSet<8> &Set : Lookups) {
19161
0
      if (Set.empty())
19162
0
        continue;
19163
0
      ResSet.append(Set.begin(), Set.end());
19164
      // The last item marks the end of all declarations at the specified scope.
19165
0
      ResSet.addDecl(Set[Set.size() - 1]);
19166
0
    }
19167
0
    return UnresolvedLookupExpr::Create(
19168
0
        SemaRef.Context, /*NamingClass=*/nullptr,
19169
0
        ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
19170
0
        /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
19171
0
  }
19172
  // Lookup inside the classes.
19173
  // C++ [over.match.oper]p3:
19174
  //   For a unary operator @ with an operand of a type whose
19175
  //   cv-unqualified version is T1, and for a binary operator @ with
19176
  //   a left operand of a type whose cv-unqualified version is T1 and
19177
  //   a right operand of a type whose cv-unqualified version is T2,
19178
  //   three sets of candidate functions, designated member
19179
  //   candidates, non-member candidates and built-in candidates, are
19180
  //   constructed as follows:
19181
  //     -- If T1 is a complete class type or a class currently being
19182
  //        defined, the set of member candidates is the result of the
19183
  //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
19184
  //        the set of member candidates is empty.
19185
0
  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
19186
0
  Lookup.suppressDiagnostics();
19187
0
  if (const auto *TyRec = Ty->getAs<RecordType>()) {
19188
    // Complete the type if it can be completed.
19189
    // If the type is neither complete nor being defined, bail out now.
19190
0
    if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
19191
0
        TyRec->getDecl()->getDefinition()) {
19192
0
      Lookup.clear();
19193
0
      SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
19194
0
      if (Lookup.empty()) {
19195
0
        Lookups.emplace_back();
19196
0
        Lookups.back().append(Lookup.begin(), Lookup.end());
19197
0
      }
19198
0
    }
19199
0
  }
19200
  // Perform ADL.
19201
0
  if (SemaRef.getLangOpts().CPlusPlus)
19202
0
    argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
19203
0
  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19204
0
          Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
19205
0
            if (!D->isInvalidDecl() &&
19206
0
                SemaRef.Context.hasSameType(D->getType(), Ty))
19207
0
              return D;
19208
0
            return nullptr;
19209
0
          }))
19210
0
    return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
19211
0
                                    VK_LValue, Loc);
19212
0
  if (SemaRef.getLangOpts().CPlusPlus) {
19213
0
    if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19214
0
            Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
19215
0
              if (!D->isInvalidDecl() &&
19216
0
                  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
19217
0
                  !Ty.isMoreQualifiedThan(D->getType()))
19218
0
                return D;
19219
0
              return nullptr;
19220
0
            })) {
19221
0
      CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
19222
0
                         /*DetectVirtual=*/false);
19223
0
      if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
19224
0
        if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
19225
0
                VD->getType().getUnqualifiedType()))) {
19226
0
          if (SemaRef.CheckBaseClassAccess(
19227
0
                  Loc, VD->getType(), Ty, Paths.front(),
19228
0
                  /*DiagID=*/0) != Sema::AR_inaccessible) {
19229
0
            SemaRef.BuildBasePathArray(Paths, BasePath);
19230
0
            return SemaRef.BuildDeclRefExpr(
19231
0
                VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
19232
0
          }
19233
0
        }
19234
0
      }
19235
0
    }
19236
0
  }
19237
0
  if (ReductionIdScopeSpec.isSet()) {
19238
0
    SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
19239
0
        << Ty << Range;
19240
0
    return ExprError();
19241
0
  }
19242
0
  return ExprEmpty();
19243
0
}
19244
19245
namespace {
19246
/// Data for the reduction-based clauses.
19247
struct ReductionData {
19248
  /// List of original reduction items.
19249
  SmallVector<Expr *, 8> Vars;
19250
  /// List of private copies of the reduction items.
19251
  SmallVector<Expr *, 8> Privates;
19252
  /// LHS expressions for the reduction_op expressions.
19253
  SmallVector<Expr *, 8> LHSs;
19254
  /// RHS expressions for the reduction_op expressions.
19255
  SmallVector<Expr *, 8> RHSs;
19256
  /// Reduction operation expression.
19257
  SmallVector<Expr *, 8> ReductionOps;
19258
  /// inscan copy operation expressions.
19259
  SmallVector<Expr *, 8> InscanCopyOps;
19260
  /// inscan copy temp array expressions for prefix sums.
19261
  SmallVector<Expr *, 8> InscanCopyArrayTemps;
19262
  /// inscan copy temp array element expressions for prefix sums.
19263
  SmallVector<Expr *, 8> InscanCopyArrayElems;
19264
  /// Taskgroup descriptors for the corresponding reduction items in
19265
  /// in_reduction clauses.
19266
  SmallVector<Expr *, 8> TaskgroupDescriptors;
19267
  /// List of captures for clause.
19268
  SmallVector<Decl *, 4> ExprCaptures;
19269
  /// List of postupdate expressions.
19270
  SmallVector<Expr *, 4> ExprPostUpdates;
19271
  /// Reduction modifier.
19272
  unsigned RedModifier = 0;
19273
  ReductionData() = delete;
19274
  /// Reserves required memory for the reduction data.
19275
0
  ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
19276
0
    Vars.reserve(Size);
19277
0
    Privates.reserve(Size);
19278
0
    LHSs.reserve(Size);
19279
0
    RHSs.reserve(Size);
19280
0
    ReductionOps.reserve(Size);
19281
0
    if (RedModifier == OMPC_REDUCTION_inscan) {
19282
0
      InscanCopyOps.reserve(Size);
19283
0
      InscanCopyArrayTemps.reserve(Size);
19284
0
      InscanCopyArrayElems.reserve(Size);
19285
0
    }
19286
0
    TaskgroupDescriptors.reserve(Size);
19287
0
    ExprCaptures.reserve(Size);
19288
0
    ExprPostUpdates.reserve(Size);
19289
0
  }
19290
  /// Stores reduction item and reduction operation only (required for dependent
19291
  /// reduction item).
19292
0
  void push(Expr *Item, Expr *ReductionOp) {
19293
0
    Vars.emplace_back(Item);
19294
0
    Privates.emplace_back(nullptr);
19295
0
    LHSs.emplace_back(nullptr);
19296
0
    RHSs.emplace_back(nullptr);
19297
0
    ReductionOps.emplace_back(ReductionOp);
19298
0
    TaskgroupDescriptors.emplace_back(nullptr);
19299
0
    if (RedModifier == OMPC_REDUCTION_inscan) {
19300
0
      InscanCopyOps.push_back(nullptr);
19301
0
      InscanCopyArrayTemps.push_back(nullptr);
19302
0
      InscanCopyArrayElems.push_back(nullptr);
19303
0
    }
19304
0
  }
19305
  /// Stores reduction data.
19306
  void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
19307
            Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
19308
0
            Expr *CopyArrayElem) {
19309
0
    Vars.emplace_back(Item);
19310
0
    Privates.emplace_back(Private);
19311
0
    LHSs.emplace_back(LHS);
19312
0
    RHSs.emplace_back(RHS);
19313
0
    ReductionOps.emplace_back(ReductionOp);
19314
0
    TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
19315
0
    if (RedModifier == OMPC_REDUCTION_inscan) {
19316
0
      InscanCopyOps.push_back(CopyOp);
19317
0
      InscanCopyArrayTemps.push_back(CopyArrayTemp);
19318
0
      InscanCopyArrayElems.push_back(CopyArrayElem);
19319
0
    } else {
19320
0
      assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
19321
0
             CopyArrayElem == nullptr &&
19322
0
             "Copy operation must be used for inscan reductions only.");
19323
0
    }
19324
0
  }
19325
};
19326
} // namespace
19327
19328
static bool checkOMPArraySectionConstantForReduction(
19329
    ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
19330
0
    SmallVectorImpl<llvm::APSInt> &ArraySizes) {
19331
0
  const Expr *Length = OASE->getLength();
19332
0
  if (Length == nullptr) {
19333
    // For array sections of the form [1:] or [:], we would need to analyze
19334
    // the lower bound...
19335
0
    if (OASE->getColonLocFirst().isValid())
19336
0
      return false;
19337
19338
    // This is an array subscript which has implicit length 1!
19339
0
    SingleElement = true;
19340
0
    ArraySizes.push_back(llvm::APSInt::get(1));
19341
0
  } else {
19342
0
    Expr::EvalResult Result;
19343
0
    if (!Length->EvaluateAsInt(Result, Context))
19344
0
      return false;
19345
19346
0
    llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19347
0
    SingleElement = (ConstantLengthValue.getSExtValue() == 1);
19348
0
    ArraySizes.push_back(ConstantLengthValue);
19349
0
  }
19350
19351
  // Get the base of this array section and walk up from there.
19352
0
  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
19353
19354
  // We require length = 1 for all array sections except the right-most to
19355
  // guarantee that the memory region is contiguous and has no holes in it.
19356
0
  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
19357
0
    Length = TempOASE->getLength();
19358
0
    if (Length == nullptr) {
19359
      // For array sections of the form [1:] or [:], we would need to analyze
19360
      // the lower bound...
19361
0
      if (OASE->getColonLocFirst().isValid())
19362
0
        return false;
19363
19364
      // This is an array subscript which has implicit length 1!
19365
0
      ArraySizes.push_back(llvm::APSInt::get(1));
19366
0
    } else {
19367
0
      Expr::EvalResult Result;
19368
0
      if (!Length->EvaluateAsInt(Result, Context))
19369
0
        return false;
19370
19371
0
      llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19372
0
      if (ConstantLengthValue.getSExtValue() != 1)
19373
0
        return false;
19374
19375
0
      ArraySizes.push_back(ConstantLengthValue);
19376
0
    }
19377
0
    Base = TempOASE->getBase()->IgnoreParenImpCasts();
19378
0
  }
19379
19380
  // If we have a single element, we don't need to add the implicit lengths.
19381
0
  if (!SingleElement) {
19382
0
    while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
19383
      // Has implicit length 1!
19384
0
      ArraySizes.push_back(llvm::APSInt::get(1));
19385
0
      Base = TempASE->getBase()->IgnoreParenImpCasts();
19386
0
    }
19387
0
  }
19388
19389
  // This array section can be privatized as a single value or as a constant
19390
  // sized array.
19391
0
  return true;
19392
0
}
19393
19394
static BinaryOperatorKind
19395
0
getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
19396
0
  if (BOK == BO_Add)
19397
0
    return BO_AddAssign;
19398
0
  if (BOK == BO_Mul)
19399
0
    return BO_MulAssign;
19400
0
  if (BOK == BO_And)
19401
0
    return BO_AndAssign;
19402
0
  if (BOK == BO_Or)
19403
0
    return BO_OrAssign;
19404
0
  if (BOK == BO_Xor)
19405
0
    return BO_XorAssign;
19406
0
  return BOK;
19407
0
}
19408
19409
static bool actOnOMPReductionKindClause(
19410
    Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
19411
    ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19412
    SourceLocation ColonLoc, SourceLocation EndLoc,
19413
    CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19414
0
    ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
19415
0
  DeclarationName DN = ReductionId.getName();
19416
0
  OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
19417
0
  BinaryOperatorKind BOK = BO_Comma;
19418
19419
0
  ASTContext &Context = S.Context;
19420
  // OpenMP [2.14.3.6, reduction clause]
19421
  // C
19422
  // reduction-identifier is either an identifier or one of the following
19423
  // operators: +, -, *,  &, |, ^, && and ||
19424
  // C++
19425
  // reduction-identifier is either an id-expression or one of the following
19426
  // operators: +, -, *, &, |, ^, && and ||
19427
0
  switch (OOK) {
19428
0
  case OO_Plus:
19429
0
    BOK = BO_Add;
19430
0
    break;
19431
0
  case OO_Minus:
19432
    // Minus(-) operator is not supported in TR11 (OpenMP 6.0). Setting BOK to
19433
    // BO_Comma will automatically diagnose it for OpenMP > 52 as not allowed
19434
    // reduction identifier.
19435
0
    if (S.LangOpts.OpenMP > 52)
19436
0
      BOK = BO_Comma;
19437
0
    else
19438
0
      BOK = BO_Add;
19439
0
    break;
19440
0
  case OO_Star:
19441
0
    BOK = BO_Mul;
19442
0
    break;
19443
0
  case OO_Amp:
19444
0
    BOK = BO_And;
19445
0
    break;
19446
0
  case OO_Pipe:
19447
0
    BOK = BO_Or;
19448
0
    break;
19449
0
  case OO_Caret:
19450
0
    BOK = BO_Xor;
19451
0
    break;
19452
0
  case OO_AmpAmp:
19453
0
    BOK = BO_LAnd;
19454
0
    break;
19455
0
  case OO_PipePipe:
19456
0
    BOK = BO_LOr;
19457
0
    break;
19458
0
  case OO_New:
19459
0
  case OO_Delete:
19460
0
  case OO_Array_New:
19461
0
  case OO_Array_Delete:
19462
0
  case OO_Slash:
19463
0
  case OO_Percent:
19464
0
  case OO_Tilde:
19465
0
  case OO_Exclaim:
19466
0
  case OO_Equal:
19467
0
  case OO_Less:
19468
0
  case OO_Greater:
19469
0
  case OO_LessEqual:
19470
0
  case OO_GreaterEqual:
19471
0
  case OO_PlusEqual:
19472
0
  case OO_MinusEqual:
19473
0
  case OO_StarEqual:
19474
0
  case OO_SlashEqual:
19475
0
  case OO_PercentEqual:
19476
0
  case OO_CaretEqual:
19477
0
  case OO_AmpEqual:
19478
0
  case OO_PipeEqual:
19479
0
  case OO_LessLess:
19480
0
  case OO_GreaterGreater:
19481
0
  case OO_LessLessEqual:
19482
0
  case OO_GreaterGreaterEqual:
19483
0
  case OO_EqualEqual:
19484
0
  case OO_ExclaimEqual:
19485
0
  case OO_Spaceship:
19486
0
  case OO_PlusPlus:
19487
0
  case OO_MinusMinus:
19488
0
  case OO_Comma:
19489
0
  case OO_ArrowStar:
19490
0
  case OO_Arrow:
19491
0
  case OO_Call:
19492
0
  case OO_Subscript:
19493
0
  case OO_Conditional:
19494
0
  case OO_Coawait:
19495
0
  case NUM_OVERLOADED_OPERATORS:
19496
0
    llvm_unreachable("Unexpected reduction identifier");
19497
0
  case OO_None:
19498
0
    if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
19499
0
      if (II->isStr("max"))
19500
0
        BOK = BO_GT;
19501
0
      else if (II->isStr("min"))
19502
0
        BOK = BO_LT;
19503
0
    }
19504
0
    break;
19505
0
  }
19506
19507
  // OpenMP 5.2, 5.5.5 (see page 627, line 18) reduction Clause, Restrictions
19508
  // A reduction clause with the minus (-) operator was deprecated
19509
0
  if (OOK == OO_Minus && S.LangOpts.OpenMP == 52)
19510
0
    S.Diag(ReductionId.getLoc(), diag::warn_omp_minus_in_reduction_deprecated);
19511
19512
0
  SourceRange ReductionIdRange;
19513
0
  if (ReductionIdScopeSpec.isValid())
19514
0
    ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
19515
0
  else
19516
0
    ReductionIdRange.setBegin(ReductionId.getBeginLoc());
19517
0
  ReductionIdRange.setEnd(ReductionId.getEndLoc());
19518
19519
0
  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19520
0
  bool FirstIter = true;
19521
0
  for (Expr *RefExpr : VarList) {
19522
0
    assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
19523
    // OpenMP [2.1, C/C++]
19524
    //  A list item is a variable or array section, subject to the restrictions
19525
    //  specified in Section 2.4 on page 42 and in each of the sections
19526
    // describing clauses and directives for which a list appears.
19527
    // OpenMP  [2.14.3.3, Restrictions, p.1]
19528
    //  A variable that is part of another variable (as an array or
19529
    //  structure element) cannot appear in a private clause.
19530
0
    if (!FirstIter && IR != ER)
19531
0
      ++IR;
19532
0
    FirstIter = false;
19533
0
    SourceLocation ELoc;
19534
0
    SourceRange ERange;
19535
0
    Expr *SimpleRefExpr = RefExpr;
19536
0
    auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
19537
0
                              /*AllowArraySection=*/true);
19538
0
    if (Res.second) {
19539
      // Try to find 'declare reduction' corresponding construct before using
19540
      // builtin/overloaded operators.
19541
0
      QualType Type = Context.DependentTy;
19542
0
      CXXCastPath BasePath;
19543
0
      ExprResult DeclareReductionRef = buildDeclareReductionRef(
19544
0
          S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19545
0
          ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19546
0
      Expr *ReductionOp = nullptr;
19547
0
      if (S.CurContext->isDependentContext() &&
19548
0
          (DeclareReductionRef.isUnset() ||
19549
0
           isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
19550
0
        ReductionOp = DeclareReductionRef.get();
19551
      // It will be analyzed later.
19552
0
      RD.push(RefExpr, ReductionOp);
19553
0
    }
19554
0
    ValueDecl *D = Res.first;
19555
0
    if (!D)
19556
0
      continue;
19557
19558
0
    Expr *TaskgroupDescriptor = nullptr;
19559
0
    QualType Type;
19560
0
    auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19561
0
    auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
19562
0
    if (ASE) {
19563
0
      Type = ASE->getType().getNonReferenceType();
19564
0
    } else if (OASE) {
19565
0
      QualType BaseType =
19566
0
          OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19567
0
      if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19568
0
        Type = ATy->getElementType();
19569
0
      else
19570
0
        Type = BaseType->getPointeeType();
19571
0
      Type = Type.getNonReferenceType();
19572
0
    } else {
19573
0
      Type = Context.getBaseElementType(D->getType().getNonReferenceType());
19574
0
    }
19575
0
    auto *VD = dyn_cast<VarDecl>(D);
19576
19577
    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
19578
    //  A variable that appears in a private clause must not have an incomplete
19579
    //  type or a reference type.
19580
0
    if (S.RequireCompleteType(ELoc, D->getType(),
19581
0
                              diag::err_omp_reduction_incomplete_type))
19582
0
      continue;
19583
    // OpenMP [2.14.3.6, reduction clause, Restrictions]
19584
    // A list item that appears in a reduction clause must not be
19585
    // const-qualified.
19586
0
    if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
19587
0
                                  /*AcceptIfMutable*/ false, ASE || OASE))
19588
0
      continue;
19589
19590
0
    OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
19591
    // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
19592
    //  If a list-item is a reference type then it must bind to the same object
19593
    //  for all threads of the team.
19594
0
    if (!ASE && !OASE) {
19595
0
      if (VD) {
19596
0
        VarDecl *VDDef = VD->getDefinition();
19597
0
        if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
19598
0
          DSARefChecker Check(Stack);
19599
0
          if (Check.Visit(VDDef->getInit())) {
19600
0
            S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19601
0
                << getOpenMPClauseName(ClauseKind) << ERange;
19602
0
            S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
19603
0
            continue;
19604
0
          }
19605
0
        }
19606
0
      }
19607
19608
      // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
19609
      // in a Construct]
19610
      //  Variables with the predetermined data-sharing attributes may not be
19611
      //  listed in data-sharing attributes clauses, except for the cases
19612
      //  listed below. For these exceptions only, listing a predetermined
19613
      //  variable in a data-sharing attribute clause is allowed and overrides
19614
      //  the variable's predetermined data-sharing attributes.
19615
      // OpenMP [2.14.3.6, Restrictions, p.3]
19616
      //  Any number of reduction clauses can be specified on the directive,
19617
      //  but a list item can appear only once in the reduction clauses for that
19618
      //  directive.
19619
0
      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19620
0
      if (DVar.CKind == OMPC_reduction) {
19621
0
        S.Diag(ELoc, diag::err_omp_once_referenced)
19622
0
            << getOpenMPClauseName(ClauseKind);
19623
0
        if (DVar.RefExpr)
19624
0
          S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19625
0
        continue;
19626
0
      }
19627
0
      if (DVar.CKind != OMPC_unknown) {
19628
0
        S.Diag(ELoc, diag::err_omp_wrong_dsa)
19629
0
            << getOpenMPClauseName(DVar.CKind)
19630
0
            << getOpenMPClauseName(OMPC_reduction);
19631
0
        reportOriginalDsa(S, Stack, D, DVar);
19632
0
        continue;
19633
0
      }
19634
19635
      // OpenMP [2.14.3.6, Restrictions, p.1]
19636
      //  A list item that appears in a reduction clause of a worksharing
19637
      //  construct must be shared in the parallel regions to which any of the
19638
      //  worksharing regions arising from the worksharing construct bind.
19639
0
      if (isOpenMPWorksharingDirective(CurrDir) &&
19640
0
          !isOpenMPParallelDirective(CurrDir) &&
19641
0
          !isOpenMPTeamsDirective(CurrDir)) {
19642
0
        DVar = Stack->getImplicitDSA(D, true);
19643
0
        if (DVar.CKind != OMPC_shared) {
19644
0
          S.Diag(ELoc, diag::err_omp_required_access)
19645
0
              << getOpenMPClauseName(OMPC_reduction)
19646
0
              << getOpenMPClauseName(OMPC_shared);
19647
0
          reportOriginalDsa(S, Stack, D, DVar);
19648
0
          continue;
19649
0
        }
19650
0
      }
19651
0
    } else {
19652
      // Threadprivates cannot be shared between threads, so dignose if the base
19653
      // is a threadprivate variable.
19654
0
      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19655
0
      if (DVar.CKind == OMPC_threadprivate) {
19656
0
        S.Diag(ELoc, diag::err_omp_wrong_dsa)
19657
0
            << getOpenMPClauseName(DVar.CKind)
19658
0
            << getOpenMPClauseName(OMPC_reduction);
19659
0
        reportOriginalDsa(S, Stack, D, DVar);
19660
0
        continue;
19661
0
      }
19662
0
    }
19663
19664
    // Try to find 'declare reduction' corresponding construct before using
19665
    // builtin/overloaded operators.
19666
0
    CXXCastPath BasePath;
19667
0
    ExprResult DeclareReductionRef = buildDeclareReductionRef(
19668
0
        S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19669
0
        ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19670
0
    if (DeclareReductionRef.isInvalid())
19671
0
      continue;
19672
0
    if (S.CurContext->isDependentContext() &&
19673
0
        (DeclareReductionRef.isUnset() ||
19674
0
         isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
19675
0
      RD.push(RefExpr, DeclareReductionRef.get());
19676
0
      continue;
19677
0
    }
19678
0
    if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
19679
      // Not allowed reduction identifier is found.
19680
0
      if (S.LangOpts.OpenMP > 52)
19681
0
        S.Diag(ReductionId.getBeginLoc(),
19682
0
               diag::err_omp_unknown_reduction_identifier_since_omp_6_0)
19683
0
            << Type << ReductionIdRange;
19684
0
      else
19685
0
        S.Diag(ReductionId.getBeginLoc(),
19686
0
               diag::err_omp_unknown_reduction_identifier_prior_omp_6_0)
19687
0
            << Type << ReductionIdRange;
19688
0
      continue;
19689
0
    }
19690
19691
    // OpenMP [2.14.3.6, reduction clause, Restrictions]
19692
    // The type of a list item that appears in a reduction clause must be valid
19693
    // for the reduction-identifier. For a max or min reduction in C, the type
19694
    // of the list item must be an allowed arithmetic data type: char, int,
19695
    // float, double, or _Bool, possibly modified with long, short, signed, or
19696
    // unsigned. For a max or min reduction in C++, the type of the list item
19697
    // must be an allowed arithmetic data type: char, wchar_t, int, float,
19698
    // double, or bool, possibly modified with long, short, signed, or unsigned.
19699
0
    if (DeclareReductionRef.isUnset()) {
19700
0
      if ((BOK == BO_GT || BOK == BO_LT) &&
19701
0
          !(Type->isScalarType() ||
19702
0
            (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
19703
0
        S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19704
0
            << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
19705
0
        if (!ASE && !OASE) {
19706
0
          bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19707
0
                                   VarDecl::DeclarationOnly;
19708
0
          S.Diag(D->getLocation(),
19709
0
                 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19710
0
              << D;
19711
0
        }
19712
0
        continue;
19713
0
      }
19714
0
      if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19715
0
          !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
19716
0
        S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19717
0
            << getOpenMPClauseName(ClauseKind);
19718
0
        if (!ASE && !OASE) {
19719
0
          bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19720
0
                                   VarDecl::DeclarationOnly;
19721
0
          S.Diag(D->getLocation(),
19722
0
                 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19723
0
              << D;
19724
0
        }
19725
0
        continue;
19726
0
      }
19727
0
    }
19728
19729
0
    Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
19730
0
    VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
19731
0
                                  D->hasAttrs() ? &D->getAttrs() : nullptr);
19732
0
    VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
19733
0
                                  D->hasAttrs() ? &D->getAttrs() : nullptr);
19734
0
    QualType PrivateTy = Type;
19735
19736
    // Try if we can determine constant lengths for all array sections and avoid
19737
    // the VLA.
19738
0
    bool ConstantLengthOASE = false;
19739
0
    if (OASE) {
19740
0
      bool SingleElement;
19741
0
      llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
19742
0
      ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
19743
0
          Context, OASE, SingleElement, ArraySizes);
19744
19745
      // If we don't have a single element, we must emit a constant array type.
19746
0
      if (ConstantLengthOASE && !SingleElement) {
19747
0
        for (llvm::APSInt &Size : ArraySizes)
19748
0
          PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
19749
0
                                                   ArraySizeModifier::Normal,
19750
0
                                                   /*IndexTypeQuals=*/0);
19751
0
      }
19752
0
    }
19753
19754
0
    if ((OASE && !ConstantLengthOASE) ||
19755
0
        (!OASE && !ASE &&
19756
0
         D->getType().getNonReferenceType()->isVariablyModifiedType())) {
19757
0
      if (!Context.getTargetInfo().isVLASupported()) {
19758
0
        if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
19759
0
          S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19760
0
          S.Diag(ELoc, diag::note_vla_unsupported);
19761
0
          continue;
19762
0
        } else {
19763
0
          S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19764
0
          S.targetDiag(ELoc, diag::note_vla_unsupported);
19765
0
        }
19766
0
      }
19767
      // For arrays/array sections only:
19768
      // Create pseudo array type for private copy. The size for this array will
19769
      // be generated during codegen.
19770
      // For array subscripts or single variables Private Ty is the same as Type
19771
      // (type of the variable or single array element).
19772
0
      PrivateTy = Context.getVariableArrayType(
19773
0
          Type,
19774
0
          new (Context)
19775
0
              OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
19776
0
          ArraySizeModifier::Normal, /*IndexTypeQuals=*/0, SourceRange());
19777
0
    } else if (!ASE && !OASE &&
19778
0
               Context.getAsArrayType(D->getType().getNonReferenceType())) {
19779
0
      PrivateTy = D->getType().getNonReferenceType();
19780
0
    }
19781
    // Private copy.
19782
0
    VarDecl *PrivateVD =
19783
0
        buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19784
0
                     D->hasAttrs() ? &D->getAttrs() : nullptr,
19785
0
                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19786
    // Add initializer for private variable.
19787
0
    Expr *Init = nullptr;
19788
0
    DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
19789
0
    DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
19790
0
    if (DeclareReductionRef.isUsable()) {
19791
0
      auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
19792
0
      auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19793
0
      if (DRD->getInitializer()) {
19794
0
        Init = DRDRef;
19795
0
        RHSVD->setInit(DRDRef);
19796
0
        RHSVD->setInitStyle(VarDecl::CallInit);
19797
0
      }
19798
0
    } else {
19799
0
      switch (BOK) {
19800
0
      case BO_Add:
19801
0
      case BO_Xor:
19802
0
      case BO_Or:
19803
0
      case BO_LOr:
19804
        // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
19805
0
        if (Type->isScalarType() || Type->isAnyComplexType())
19806
0
          Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
19807
0
        break;
19808
0
      case BO_Mul:
19809
0
      case BO_LAnd:
19810
0
        if (Type->isScalarType() || Type->isAnyComplexType()) {
19811
          // '*' and '&&' reduction ops - initializer is '1'.
19812
0
          Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
19813
0
        }
19814
0
        break;
19815
0
      case BO_And: {
19816
        // '&' reduction op - initializer is '~0'.
19817
0
        QualType OrigType = Type;
19818
0
        if (auto *ComplexTy = OrigType->getAs<ComplexType>())
19819
0
          Type = ComplexTy->getElementType();
19820
0
        if (Type->isRealFloatingType()) {
19821
0
          llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19822
0
              Context.getFloatTypeSemantics(Type));
19823
0
          Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19824
0
                                         Type, ELoc);
19825
0
        } else if (Type->isScalarType()) {
19826
0
          uint64_t Size = Context.getTypeSize(Type);
19827
0
          QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
19828
0
          llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19829
0
          Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19830
0
        }
19831
0
        if (Init && OrigType->isAnyComplexType()) {
19832
          // Init = 0xFFFF + 0xFFFFi;
19833
0
          auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
19834
0
          Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
19835
0
        }
19836
0
        Type = OrigType;
19837
0
        break;
19838
0
      }
19839
0
      case BO_LT:
19840
0
      case BO_GT: {
19841
        // 'min' reduction op - initializer is 'Largest representable number in
19842
        // the reduction list item type'.
19843
        // 'max' reduction op - initializer is 'Least representable number in
19844
        // the reduction list item type'.
19845
0
        if (Type->isIntegerType() || Type->isPointerType()) {
19846
0
          bool IsSigned = Type->hasSignedIntegerRepresentation();
19847
0
          uint64_t Size = Context.getTypeSize(Type);
19848
0
          QualType IntTy =
19849
0
              Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
19850
0
          llvm::APInt InitValue =
19851
0
              (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
19852
0
                                        : llvm::APInt::getMinValue(Size)
19853
0
              : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
19854
0
                             : llvm::APInt::getMaxValue(Size);
19855
0
          Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19856
0
          if (Type->isPointerType()) {
19857
            // Cast to pointer type.
19858
0
            ExprResult CastExpr = S.BuildCStyleCastExpr(
19859
0
                ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
19860
0
            if (CastExpr.isInvalid())
19861
0
              continue;
19862
0
            Init = CastExpr.get();
19863
0
          }
19864
0
        } else if (Type->isRealFloatingType()) {
19865
0
          llvm::APFloat InitValue = llvm::APFloat::getLargest(
19866
0
              Context.getFloatTypeSemantics(Type), BOK != BO_LT);
19867
0
          Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19868
0
                                         Type, ELoc);
19869
0
        }
19870
0
        break;
19871
0
      }
19872
0
      case BO_PtrMemD:
19873
0
      case BO_PtrMemI:
19874
0
      case BO_MulAssign:
19875
0
      case BO_Div:
19876
0
      case BO_Rem:
19877
0
      case BO_Sub:
19878
0
      case BO_Shl:
19879
0
      case BO_Shr:
19880
0
      case BO_LE:
19881
0
      case BO_GE:
19882
0
      case BO_EQ:
19883
0
      case BO_NE:
19884
0
      case BO_Cmp:
19885
0
      case BO_AndAssign:
19886
0
      case BO_XorAssign:
19887
0
      case BO_OrAssign:
19888
0
      case BO_Assign:
19889
0
      case BO_AddAssign:
19890
0
      case BO_SubAssign:
19891
0
      case BO_DivAssign:
19892
0
      case BO_RemAssign:
19893
0
      case BO_ShlAssign:
19894
0
      case BO_ShrAssign:
19895
0
      case BO_Comma:
19896
0
        llvm_unreachable("Unexpected reduction operation");
19897
0
      }
19898
0
    }
19899
0
    if (Init && DeclareReductionRef.isUnset()) {
19900
0
      S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
19901
      // Store initializer for single element in private copy. Will be used
19902
      // during codegen.
19903
0
      PrivateVD->setInit(RHSVD->getInit());
19904
0
      PrivateVD->setInitStyle(RHSVD->getInitStyle());
19905
0
    } else if (!Init) {
19906
0
      S.ActOnUninitializedDecl(RHSVD);
19907
      // Store initializer for single element in private copy. Will be used
19908
      // during codegen.
19909
0
      PrivateVD->setInit(RHSVD->getInit());
19910
0
      PrivateVD->setInitStyle(RHSVD->getInitStyle());
19911
0
    }
19912
0
    if (RHSVD->isInvalidDecl())
19913
0
      continue;
19914
0
    if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
19915
0
      S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19916
0
          << Type << ReductionIdRange;
19917
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19918
0
                               VarDecl::DeclarationOnly;
19919
0
      S.Diag(D->getLocation(),
19920
0
             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19921
0
          << D;
19922
0
      continue;
19923
0
    }
19924
0
    DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
19925
0
    ExprResult ReductionOp;
19926
0
    if (DeclareReductionRef.isUsable()) {
19927
0
      QualType RedTy = DeclareReductionRef.get()->getType();
19928
0
      QualType PtrRedTy = Context.getPointerType(RedTy);
19929
0
      ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
19930
0
      ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
19931
0
      if (!BasePath.empty()) {
19932
0
        LHS = S.DefaultLvalueConversion(LHS.get());
19933
0
        RHS = S.DefaultLvalueConversion(RHS.get());
19934
0
        LHS = ImplicitCastExpr::Create(
19935
0
            Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
19936
0
            LHS.get()->getValueKind(), FPOptionsOverride());
19937
0
        RHS = ImplicitCastExpr::Create(
19938
0
            Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
19939
0
            RHS.get()->getValueKind(), FPOptionsOverride());
19940
0
      }
19941
0
      FunctionProtoType::ExtProtoInfo EPI;
19942
0
      QualType Params[] = {PtrRedTy, PtrRedTy};
19943
0
      QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
19944
0
      auto *OVE = new (Context) OpaqueValueExpr(
19945
0
          ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
19946
0
          S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
19947
0
      Expr *Args[] = {LHS.get(), RHS.get()};
19948
0
      ReductionOp =
19949
0
          CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
19950
0
                           S.CurFPFeatureOverrides());
19951
0
    } else {
19952
0
      BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
19953
0
      if (Type->isRecordType() && CombBOK != BOK) {
19954
0
        Sema::TentativeAnalysisScope Trap(S);
19955
0
        ReductionOp =
19956
0
            S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19957
0
                         CombBOK, LHSDRE, RHSDRE);
19958
0
      }
19959
0
      if (!ReductionOp.isUsable()) {
19960
0
        ReductionOp =
19961
0
            S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
19962
0
                         LHSDRE, RHSDRE);
19963
0
        if (ReductionOp.isUsable()) {
19964
0
          if (BOK != BO_LT && BOK != BO_GT) {
19965
0
            ReductionOp =
19966
0
                S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19967
0
                             BO_Assign, LHSDRE, ReductionOp.get());
19968
0
          } else {
19969
0
            auto *ConditionalOp = new (Context)
19970
0
                ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
19971
0
                                    RHSDRE, Type, VK_LValue, OK_Ordinary);
19972
0
            ReductionOp =
19973
0
                S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19974
0
                             BO_Assign, LHSDRE, ConditionalOp);
19975
0
          }
19976
0
        }
19977
0
      }
19978
0
      if (ReductionOp.isUsable())
19979
0
        ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
19980
0
                                            /*DiscardedValue*/ false);
19981
0
      if (!ReductionOp.isUsable())
19982
0
        continue;
19983
0
    }
19984
19985
    // Add copy operations for inscan reductions.
19986
    // LHS = RHS;
19987
0
    ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
19988
0
    if (ClauseKind == OMPC_reduction &&
19989
0
        RD.RedModifier == OMPC_REDUCTION_inscan) {
19990
0
      ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
19991
0
      CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
19992
0
                               RHS.get());
19993
0
      if (!CopyOpRes.isUsable())
19994
0
        continue;
19995
0
      CopyOpRes =
19996
0
          S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
19997
0
      if (!CopyOpRes.isUsable())
19998
0
        continue;
19999
      // For simd directive and simd-based directives in simd mode no need to
20000
      // construct temp array, need just a single temp element.
20001
0
      if (Stack->getCurrentDirective() == OMPD_simd ||
20002
0
          (S.getLangOpts().OpenMPSimd &&
20003
0
           isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
20004
0
        VarDecl *TempArrayVD =
20005
0
            buildVarDecl(S, ELoc, PrivateTy, D->getName(),
20006
0
                         D->hasAttrs() ? &D->getAttrs() : nullptr);
20007
        // Add a constructor to the temp decl.
20008
0
        S.ActOnUninitializedDecl(TempArrayVD);
20009
0
        TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
20010
0
      } else {
20011
        // Build temp array for prefix sum.
20012
0
        auto *Dim = new (S.Context)
20013
0
            OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
20014
0
        QualType ArrayTy = S.Context.getVariableArrayType(
20015
0
            PrivateTy, Dim, ArraySizeModifier::Normal,
20016
0
            /*IndexTypeQuals=*/0, {ELoc, ELoc});
20017
0
        VarDecl *TempArrayVD =
20018
0
            buildVarDecl(S, ELoc, ArrayTy, D->getName(),
20019
0
                         D->hasAttrs() ? &D->getAttrs() : nullptr);
20020
        // Add a constructor to the temp decl.
20021
0
        S.ActOnUninitializedDecl(TempArrayVD);
20022
0
        TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
20023
0
        TempArrayElem =
20024
0
            S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
20025
0
        auto *Idx = new (S.Context)
20026
0
            OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
20027
0
        TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
20028
0
                                                          ELoc, Idx, ELoc);
20029
0
      }
20030
0
    }
20031
20032
    // OpenMP [2.15.4.6, Restrictions, p.2]
20033
    // A list item that appears in an in_reduction clause of a task construct
20034
    // must appear in a task_reduction clause of a construct associated with a
20035
    // taskgroup region that includes the participating task in its taskgroup
20036
    // set. The construct associated with the innermost region that meets this
20037
    // condition must specify the same reduction-identifier as the in_reduction
20038
    // clause.
20039
0
    if (ClauseKind == OMPC_in_reduction) {
20040
0
      SourceRange ParentSR;
20041
0
      BinaryOperatorKind ParentBOK;
20042
0
      const Expr *ParentReductionOp = nullptr;
20043
0
      Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
20044
0
      DSAStackTy::DSAVarData ParentBOKDSA =
20045
0
          Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
20046
0
                                                  ParentBOKTD);
20047
0
      DSAStackTy::DSAVarData ParentReductionOpDSA =
20048
0
          Stack->getTopMostTaskgroupReductionData(
20049
0
              D, ParentSR, ParentReductionOp, ParentReductionOpTD);
20050
0
      bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
20051
0
      bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
20052
0
      if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
20053
0
          (DeclareReductionRef.isUsable() && IsParentBOK) ||
20054
0
          (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
20055
0
        bool EmitError = true;
20056
0
        if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
20057
0
          llvm::FoldingSetNodeID RedId, ParentRedId;
20058
0
          ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
20059
0
          DeclareReductionRef.get()->Profile(RedId, Context,
20060
0
                                             /*Canonical=*/true);
20061
0
          EmitError = RedId != ParentRedId;
20062
0
        }
20063
0
        if (EmitError) {
20064
0
          S.Diag(ReductionId.getBeginLoc(),
20065
0
                 diag::err_omp_reduction_identifier_mismatch)
20066
0
              << ReductionIdRange << RefExpr->getSourceRange();
20067
0
          S.Diag(ParentSR.getBegin(),
20068
0
                 diag::note_omp_previous_reduction_identifier)
20069
0
              << ParentSR
20070
0
              << (IsParentBOK ? ParentBOKDSA.RefExpr
20071
0
                              : ParentReductionOpDSA.RefExpr)
20072
0
                     ->getSourceRange();
20073
0
          continue;
20074
0
        }
20075
0
      }
20076
0
      TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
20077
0
    }
20078
20079
0
    DeclRefExpr *Ref = nullptr;
20080
0
    Expr *VarsExpr = RefExpr->IgnoreParens();
20081
0
    if (!VD && !S.CurContext->isDependentContext()) {
20082
0
      if (ASE || OASE) {
20083
0
        TransformExprToCaptures RebuildToCapture(S, D);
20084
0
        VarsExpr =
20085
0
            RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
20086
0
        Ref = RebuildToCapture.getCapturedExpr();
20087
0
      } else {
20088
0
        VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
20089
0
      }
20090
0
      if (!S.isOpenMPCapturedDecl(D)) {
20091
0
        RD.ExprCaptures.emplace_back(Ref->getDecl());
20092
0
        if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20093
0
          ExprResult RefRes = S.DefaultLvalueConversion(Ref);
20094
0
          if (!RefRes.isUsable())
20095
0
            continue;
20096
0
          ExprResult PostUpdateRes =
20097
0
              S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
20098
0
                           RefRes.get());
20099
0
          if (!PostUpdateRes.isUsable())
20100
0
            continue;
20101
0
          if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
20102
0
              Stack->getCurrentDirective() == OMPD_taskgroup) {
20103
0
            S.Diag(RefExpr->getExprLoc(),
20104
0
                   diag::err_omp_reduction_non_addressable_expression)
20105
0
                << RefExpr->getSourceRange();
20106
0
            continue;
20107
0
          }
20108
0
          RD.ExprPostUpdates.emplace_back(
20109
0
              S.IgnoredValueConversions(PostUpdateRes.get()).get());
20110
0
        }
20111
0
      }
20112
0
    }
20113
    // All reduction items are still marked as reduction (to do not increase
20114
    // code base size).
20115
0
    unsigned Modifier = RD.RedModifier;
20116
    // Consider task_reductions as reductions with task modifier. Required for
20117
    // correct analysis of in_reduction clauses.
20118
0
    if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
20119
0
      Modifier = OMPC_REDUCTION_task;
20120
0
    Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
20121
0
                  ASE || OASE);
20122
0
    if (Modifier == OMPC_REDUCTION_task &&
20123
0
        (CurrDir == OMPD_taskgroup ||
20124
0
         ((isOpenMPParallelDirective(CurrDir) ||
20125
0
           isOpenMPWorksharingDirective(CurrDir)) &&
20126
0
          !isOpenMPSimdDirective(CurrDir)))) {
20127
0
      if (DeclareReductionRef.isUsable())
20128
0
        Stack->addTaskgroupReductionData(D, ReductionIdRange,
20129
0
                                         DeclareReductionRef.get());
20130
0
      else
20131
0
        Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
20132
0
    }
20133
0
    RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
20134
0
            TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
20135
0
            TempArrayElem.get());
20136
0
  }
20137
0
  return RD.Vars.empty();
20138
0
}
20139
20140
OMPClause *Sema::ActOnOpenMPReductionClause(
20141
    ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
20142
    SourceLocation StartLoc, SourceLocation LParenLoc,
20143
    SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
20144
    CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20145
0
    ArrayRef<Expr *> UnresolvedReductions) {
20146
0
  if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
20147
0
    Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
20148
0
        << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
20149
0
                                   /*Last=*/OMPC_REDUCTION_unknown)
20150
0
        << getOpenMPClauseName(OMPC_reduction);
20151
0
    return nullptr;
20152
0
  }
20153
  // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
20154
  // A reduction clause with the inscan reduction-modifier may only appear on a
20155
  // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
20156
  // construct, a parallel worksharing-loop construct or a parallel
20157
  // worksharing-loop SIMD construct.
20158
0
  if (Modifier == OMPC_REDUCTION_inscan &&
20159
0
      (DSAStack->getCurrentDirective() != OMPD_for &&
20160
0
       DSAStack->getCurrentDirective() != OMPD_for_simd &&
20161
0
       DSAStack->getCurrentDirective() != OMPD_simd &&
20162
0
       DSAStack->getCurrentDirective() != OMPD_parallel_for &&
20163
0
       DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
20164
0
    Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
20165
0
    return nullptr;
20166
0
  }
20167
20168
0
  ReductionData RD(VarList.size(), Modifier);
20169
0
  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
20170
0
                                  StartLoc, LParenLoc, ColonLoc, EndLoc,
20171
0
                                  ReductionIdScopeSpec, ReductionId,
20172
0
                                  UnresolvedReductions, RD))
20173
0
    return nullptr;
20174
20175
0
  return OMPReductionClause::Create(
20176
0
      Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
20177
0
      RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20178
0
      RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
20179
0
      RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
20180
0
      buildPreInits(Context, RD.ExprCaptures),
20181
0
      buildPostUpdate(*this, RD.ExprPostUpdates));
20182
0
}
20183
20184
OMPClause *Sema::ActOnOpenMPTaskReductionClause(
20185
    ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
20186
    SourceLocation ColonLoc, SourceLocation EndLoc,
20187
    CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20188
0
    ArrayRef<Expr *> UnresolvedReductions) {
20189
0
  ReductionData RD(VarList.size());
20190
0
  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
20191
0
                                  StartLoc, LParenLoc, ColonLoc, EndLoc,
20192
0
                                  ReductionIdScopeSpec, ReductionId,
20193
0
                                  UnresolvedReductions, RD))
20194
0
    return nullptr;
20195
20196
0
  return OMPTaskReductionClause::Create(
20197
0
      Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20198
0
      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20199
0
      RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
20200
0
      buildPreInits(Context, RD.ExprCaptures),
20201
0
      buildPostUpdate(*this, RD.ExprPostUpdates));
20202
0
}
20203
20204
OMPClause *Sema::ActOnOpenMPInReductionClause(
20205
    ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
20206
    SourceLocation ColonLoc, SourceLocation EndLoc,
20207
    CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20208
0
    ArrayRef<Expr *> UnresolvedReductions) {
20209
0
  ReductionData RD(VarList.size());
20210
0
  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
20211
0
                                  StartLoc, LParenLoc, ColonLoc, EndLoc,
20212
0
                                  ReductionIdScopeSpec, ReductionId,
20213
0
                                  UnresolvedReductions, RD))
20214
0
    return nullptr;
20215
20216
0
  return OMPInReductionClause::Create(
20217
0
      Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20218
0
      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20219
0
      RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
20220
0
      buildPreInits(Context, RD.ExprCaptures),
20221
0
      buildPostUpdate(*this, RD.ExprPostUpdates));
20222
0
}
20223
20224
bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
20225
0
                                     SourceLocation LinLoc) {
20226
0
  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
20227
0
      LinKind == OMPC_LINEAR_unknown || LinKind == OMPC_LINEAR_step) {
20228
0
    Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
20229
0
    return true;
20230
0
  }
20231
0
  return false;
20232
0
}
20233
20234
bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
20235
                                 OpenMPLinearClauseKind LinKind, QualType Type,
20236
0
                                 bool IsDeclareSimd) {
20237
0
  const auto *VD = dyn_cast_or_null<VarDecl>(D);
20238
  // A variable must not have an incomplete type or a reference type.
20239
0
  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
20240
0
    return true;
20241
0
  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
20242
0
      !Type->isReferenceType()) {
20243
0
    Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
20244
0
        << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
20245
0
    return true;
20246
0
  }
20247
0
  Type = Type.getNonReferenceType();
20248
20249
  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
20250
  // A variable that is privatized must not have a const-qualified type
20251
  // unless it is of class type with a mutable member. This restriction does
20252
  // not apply to the firstprivate clause, nor to the linear clause on
20253
  // declarative directives (like declare simd).
20254
0
  if (!IsDeclareSimd &&
20255
0
      rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
20256
0
    return true;
20257
20258
  // A list item must be of integral or pointer type.
20259
0
  Type = Type.getUnqualifiedType().getCanonicalType();
20260
0
  const auto *Ty = Type.getTypePtrOrNull();
20261
0
  if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
20262
0
              !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
20263
0
    Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
20264
0
    if (D) {
20265
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20266
0
                               VarDecl::DeclarationOnly;
20267
0
      Diag(D->getLocation(),
20268
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20269
0
          << D;
20270
0
    }
20271
0
    return true;
20272
0
  }
20273
0
  return false;
20274
0
}
20275
20276
OMPClause *Sema::ActOnOpenMPLinearClause(
20277
    ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
20278
    SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
20279
    SourceLocation LinLoc, SourceLocation ColonLoc,
20280
0
    SourceLocation StepModifierLoc, SourceLocation EndLoc) {
20281
0
  SmallVector<Expr *, 8> Vars;
20282
0
  SmallVector<Expr *, 8> Privates;
20283
0
  SmallVector<Expr *, 8> Inits;
20284
0
  SmallVector<Decl *, 4> ExprCaptures;
20285
0
  SmallVector<Expr *, 4> ExprPostUpdates;
20286
  // OpenMP 5.2 [Section 5.4.6, linear clause]
20287
  // step-simple-modifier is exclusive, can't be used with 'val', 'uval', or
20288
  // 'ref'
20289
0
  if (LinLoc.isValid() && StepModifierLoc.isInvalid() && Step &&
20290
0
      getLangOpts().OpenMP >= 52)
20291
0
    Diag(Step->getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
20292
0
  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
20293
0
    LinKind = OMPC_LINEAR_val;
20294
0
  for (Expr *RefExpr : VarList) {
20295
0
    assert(RefExpr && "NULL expr in OpenMP linear clause.");
20296
0
    SourceLocation ELoc;
20297
0
    SourceRange ERange;
20298
0
    Expr *SimpleRefExpr = RefExpr;
20299
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20300
0
    if (Res.second) {
20301
      // It will be analyzed later.
20302
0
      Vars.push_back(RefExpr);
20303
0
      Privates.push_back(nullptr);
20304
0
      Inits.push_back(nullptr);
20305
0
    }
20306
0
    ValueDecl *D = Res.first;
20307
0
    if (!D)
20308
0
      continue;
20309
20310
0
    QualType Type = D->getType();
20311
0
    auto *VD = dyn_cast<VarDecl>(D);
20312
20313
    // OpenMP [2.14.3.7, linear clause]
20314
    //  A list-item cannot appear in more than one linear clause.
20315
    //  A list-item that appears in a linear clause cannot appear in any
20316
    //  other data-sharing attribute clause.
20317
0
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
20318
0
    if (DVar.RefExpr) {
20319
0
      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
20320
0
                                          << getOpenMPClauseName(OMPC_linear);
20321
0
      reportOriginalDsa(*this, DSAStack, D, DVar);
20322
0
      continue;
20323
0
    }
20324
20325
0
    if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
20326
0
      continue;
20327
0
    Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20328
20329
    // Build private copy of original var.
20330
0
    VarDecl *Private =
20331
0
        buildVarDecl(*this, ELoc, Type, D->getName(),
20332
0
                     D->hasAttrs() ? &D->getAttrs() : nullptr,
20333
0
                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20334
0
    DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
20335
    // Build var to save initial value.
20336
0
    VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
20337
0
    Expr *InitExpr;
20338
0
    DeclRefExpr *Ref = nullptr;
20339
0
    if (!VD && !CurContext->isDependentContext()) {
20340
0
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20341
0
      if (!isOpenMPCapturedDecl(D)) {
20342
0
        ExprCaptures.push_back(Ref->getDecl());
20343
0
        if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20344
0
          ExprResult RefRes = DefaultLvalueConversion(Ref);
20345
0
          if (!RefRes.isUsable())
20346
0
            continue;
20347
0
          ExprResult PostUpdateRes =
20348
0
              BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
20349
0
                         SimpleRefExpr, RefRes.get());
20350
0
          if (!PostUpdateRes.isUsable())
20351
0
            continue;
20352
0
          ExprPostUpdates.push_back(
20353
0
              IgnoredValueConversions(PostUpdateRes.get()).get());
20354
0
        }
20355
0
      }
20356
0
    }
20357
0
    if (LinKind == OMPC_LINEAR_uval)
20358
0
      InitExpr = VD ? VD->getInit() : SimpleRefExpr;
20359
0
    else
20360
0
      InitExpr = VD ? SimpleRefExpr : Ref;
20361
0
    AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
20362
0
                         /*DirectInit=*/false);
20363
0
    DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
20364
20365
0
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
20366
0
    Vars.push_back((VD || CurContext->isDependentContext())
20367
0
                       ? RefExpr->IgnoreParens()
20368
0
                       : Ref);
20369
0
    Privates.push_back(PrivateRef);
20370
0
    Inits.push_back(InitRef);
20371
0
  }
20372
20373
0
  if (Vars.empty())
20374
0
    return nullptr;
20375
20376
0
  Expr *StepExpr = Step;
20377
0
  Expr *CalcStepExpr = nullptr;
20378
0
  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
20379
0
      !Step->isInstantiationDependent() &&
20380
0
      !Step->containsUnexpandedParameterPack()) {
20381
0
    SourceLocation StepLoc = Step->getBeginLoc();
20382
0
    ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
20383
0
    if (Val.isInvalid())
20384
0
      return nullptr;
20385
0
    StepExpr = Val.get();
20386
20387
    // Build var to save the step value.
20388
0
    VarDecl *SaveVar =
20389
0
        buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
20390
0
    ExprResult SaveRef =
20391
0
        buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
20392
0
    ExprResult CalcStep =
20393
0
        BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
20394
0
    CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
20395
20396
    // Warn about zero linear step (it would be probably better specified as
20397
    // making corresponding variables 'const').
20398
0
    if (std::optional<llvm::APSInt> Result =
20399
0
            StepExpr->getIntegerConstantExpr(Context)) {
20400
0
      if (!Result->isNegative() && !Result->isStrictlyPositive())
20401
0
        Diag(StepLoc, diag::warn_omp_linear_step_zero)
20402
0
            << Vars[0] << (Vars.size() > 1);
20403
0
    } else if (CalcStep.isUsable()) {
20404
      // Calculate the step beforehand instead of doing this on each iteration.
20405
      // (This is not used if the number of iterations may be kfold-ed).
20406
0
      CalcStepExpr = CalcStep.get();
20407
0
    }
20408
0
  }
20409
20410
0
  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
20411
0
                                 ColonLoc, StepModifierLoc, EndLoc, Vars,
20412
0
                                 Privates, Inits, StepExpr, CalcStepExpr,
20413
0
                                 buildPreInits(Context, ExprCaptures),
20414
0
                                 buildPostUpdate(*this, ExprPostUpdates));
20415
0
}
20416
20417
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
20418
                                     Expr *NumIterations, Sema &SemaRef,
20419
0
                                     Scope *S, DSAStackTy *Stack) {
20420
  // Walk the vars and build update/final expressions for the CodeGen.
20421
0
  SmallVector<Expr *, 8> Updates;
20422
0
  SmallVector<Expr *, 8> Finals;
20423
0
  SmallVector<Expr *, 8> UsedExprs;
20424
0
  Expr *Step = Clause.getStep();
20425
0
  Expr *CalcStep = Clause.getCalcStep();
20426
  // OpenMP [2.14.3.7, linear clause]
20427
  // If linear-step is not specified it is assumed to be 1.
20428
0
  if (!Step)
20429
0
    Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
20430
0
  else if (CalcStep)
20431
0
    Step = cast<BinaryOperator>(CalcStep)->getLHS();
20432
0
  bool HasErrors = false;
20433
0
  auto CurInit = Clause.inits().begin();
20434
0
  auto CurPrivate = Clause.privates().begin();
20435
0
  OpenMPLinearClauseKind LinKind = Clause.getModifier();
20436
0
  for (Expr *RefExpr : Clause.varlists()) {
20437
0
    SourceLocation ELoc;
20438
0
    SourceRange ERange;
20439
0
    Expr *SimpleRefExpr = RefExpr;
20440
0
    auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20441
0
    ValueDecl *D = Res.first;
20442
0
    if (Res.second || !D) {
20443
0
      Updates.push_back(nullptr);
20444
0
      Finals.push_back(nullptr);
20445
0
      HasErrors = true;
20446
0
      continue;
20447
0
    }
20448
0
    auto &&Info = Stack->isLoopControlVariable(D);
20449
    // OpenMP [2.15.11, distribute simd Construct]
20450
    // A list item may not appear in a linear clause, unless it is the loop
20451
    // iteration variable.
20452
0
    if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
20453
0
        isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
20454
0
      SemaRef.Diag(ELoc,
20455
0
                   diag::err_omp_linear_distribute_var_non_loop_iteration);
20456
0
      Updates.push_back(nullptr);
20457
0
      Finals.push_back(nullptr);
20458
0
      HasErrors = true;
20459
0
      continue;
20460
0
    }
20461
0
    Expr *InitExpr = *CurInit;
20462
20463
    // Build privatized reference to the current linear var.
20464
0
    auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20465
0
    Expr *CapturedRef;
20466
0
    if (LinKind == OMPC_LINEAR_uval)
20467
0
      CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20468
0
    else
20469
0
      CapturedRef =
20470
0
          buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
20471
0
                           DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20472
0
                           /*RefersToCapture=*/true);
20473
20474
    // Build update: Var = InitExpr + IV * Step
20475
0
    ExprResult Update;
20476
0
    if (!Info.first)
20477
0
      Update = buildCounterUpdate(
20478
0
          SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20479
0
          /*Subtract=*/false, /*IsNonRectangularLB=*/false);
20480
0
    else
20481
0
      Update = *CurPrivate;
20482
0
    Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
20483
0
                                         /*DiscardedValue*/ false);
20484
20485
    // Build final: Var = PrivCopy;
20486
0
    ExprResult Final;
20487
0
    if (!Info.first)
20488
0
      Final = SemaRef.BuildBinOp(
20489
0
          S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20490
0
          SemaRef.DefaultLvalueConversion(*CurPrivate).get());
20491
0
    else
20492
0
      Final = *CurPrivate;
20493
0
    Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
20494
0
                                        /*DiscardedValue*/ false);
20495
20496
0
    if (!Update.isUsable() || !Final.isUsable()) {
20497
0
      Updates.push_back(nullptr);
20498
0
      Finals.push_back(nullptr);
20499
0
      UsedExprs.push_back(nullptr);
20500
0
      HasErrors = true;
20501
0
    } else {
20502
0
      Updates.push_back(Update.get());
20503
0
      Finals.push_back(Final.get());
20504
0
      if (!Info.first)
20505
0
        UsedExprs.push_back(SimpleRefExpr);
20506
0
    }
20507
0
    ++CurInit;
20508
0
    ++CurPrivate;
20509
0
  }
20510
0
  if (Expr *S = Clause.getStep())
20511
0
    UsedExprs.push_back(S);
20512
  // Fill the remaining part with the nullptr.
20513
0
  UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
20514
0
  Clause.setUpdates(Updates);
20515
0
  Clause.setFinals(Finals);
20516
0
  Clause.setUsedExprs(UsedExprs);
20517
0
  return HasErrors;
20518
0
}
20519
20520
OMPClause *Sema::ActOnOpenMPAlignedClause(
20521
    ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
20522
0
    SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
20523
0
  SmallVector<Expr *, 8> Vars;
20524
0
  for (Expr *RefExpr : VarList) {
20525
0
    assert(RefExpr && "NULL expr in OpenMP linear clause.");
20526
0
    SourceLocation ELoc;
20527
0
    SourceRange ERange;
20528
0
    Expr *SimpleRefExpr = RefExpr;
20529
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20530
0
    if (Res.second) {
20531
      // It will be analyzed later.
20532
0
      Vars.push_back(RefExpr);
20533
0
    }
20534
0
    ValueDecl *D = Res.first;
20535
0
    if (!D)
20536
0
      continue;
20537
20538
0
    QualType QType = D->getType();
20539
0
    auto *VD = dyn_cast<VarDecl>(D);
20540
20541
    // OpenMP  [2.8.1, simd construct, Restrictions]
20542
    // The type of list items appearing in the aligned clause must be
20543
    // array, pointer, reference to array, or reference to pointer.
20544
0
    QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20545
0
    const Type *Ty = QType.getTypePtrOrNull();
20546
0
    if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
20547
0
      Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20548
0
          << QType << getLangOpts().CPlusPlus << ERange;
20549
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20550
0
                               VarDecl::DeclarationOnly;
20551
0
      Diag(D->getLocation(),
20552
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20553
0
          << D;
20554
0
      continue;
20555
0
    }
20556
20557
    // OpenMP  [2.8.1, simd construct, Restrictions]
20558
    // A list-item cannot appear in more than one aligned clause.
20559
0
    if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
20560
0
      Diag(ELoc, diag::err_omp_used_in_clause_twice)
20561
0
          << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20562
0
      Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20563
0
          << getOpenMPClauseName(OMPC_aligned);
20564
0
      continue;
20565
0
    }
20566
20567
0
    DeclRefExpr *Ref = nullptr;
20568
0
    if (!VD && isOpenMPCapturedDecl(D))
20569
0
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20570
0
    Vars.push_back(DefaultFunctionArrayConversion(
20571
0
                       (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
20572
0
                       .get());
20573
0
  }
20574
20575
  // OpenMP [2.8.1, simd construct, Description]
20576
  // The parameter of the aligned clause, alignment, must be a constant
20577
  // positive integer expression.
20578
  // If no optional parameter is specified, implementation-defined default
20579
  // alignments for SIMD instructions on the target platforms are assumed.
20580
0
  if (Alignment != nullptr) {
20581
0
    ExprResult AlignResult =
20582
0
        VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
20583
0
    if (AlignResult.isInvalid())
20584
0
      return nullptr;
20585
0
    Alignment = AlignResult.get();
20586
0
  }
20587
0
  if (Vars.empty())
20588
0
    return nullptr;
20589
20590
0
  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20591
0
                                  EndLoc, Vars, Alignment);
20592
0
}
20593
20594
OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
20595
                                         SourceLocation StartLoc,
20596
                                         SourceLocation LParenLoc,
20597
0
                                         SourceLocation EndLoc) {
20598
0
  SmallVector<Expr *, 8> Vars;
20599
0
  SmallVector<Expr *, 8> SrcExprs;
20600
0
  SmallVector<Expr *, 8> DstExprs;
20601
0
  SmallVector<Expr *, 8> AssignmentOps;
20602
0
  for (Expr *RefExpr : VarList) {
20603
0
    assert(RefExpr && "NULL expr in OpenMP copyin clause.");
20604
0
    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20605
      // It will be analyzed later.
20606
0
      Vars.push_back(RefExpr);
20607
0
      SrcExprs.push_back(nullptr);
20608
0
      DstExprs.push_back(nullptr);
20609
0
      AssignmentOps.push_back(nullptr);
20610
0
      continue;
20611
0
    }
20612
20613
0
    SourceLocation ELoc = RefExpr->getExprLoc();
20614
    // OpenMP [2.1, C/C++]
20615
    //  A list item is a variable name.
20616
    // OpenMP  [2.14.4.1, Restrictions, p.1]
20617
    //  A list item that appears in a copyin clause must be threadprivate.
20618
0
    auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20619
0
    if (!DE || !isa<VarDecl>(DE->getDecl())) {
20620
0
      Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20621
0
          << 0 << RefExpr->getSourceRange();
20622
0
      continue;
20623
0
    }
20624
20625
0
    Decl *D = DE->getDecl();
20626
0
    auto *VD = cast<VarDecl>(D);
20627
20628
0
    QualType Type = VD->getType();
20629
0
    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
20630
      // It will be analyzed later.
20631
0
      Vars.push_back(DE);
20632
0
      SrcExprs.push_back(nullptr);
20633
0
      DstExprs.push_back(nullptr);
20634
0
      AssignmentOps.push_back(nullptr);
20635
0
      continue;
20636
0
    }
20637
20638
    // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
20639
    //  A list item that appears in a copyin clause must be threadprivate.
20640
0
    if (!DSAStack->isThreadPrivate(VD)) {
20641
0
      Diag(ELoc, diag::err_omp_required_access)
20642
0
          << getOpenMPClauseName(OMPC_copyin)
20643
0
          << getOpenMPDirectiveName(OMPD_threadprivate);
20644
0
      continue;
20645
0
    }
20646
20647
    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20648
    //  A variable of class type (or array thereof) that appears in a
20649
    //  copyin clause requires an accessible, unambiguous copy assignment
20650
    //  operator for the class type.
20651
0
    QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
20652
0
    VarDecl *SrcVD =
20653
0
        buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
20654
0
                     ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20655
0
    DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
20656
0
        *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
20657
0
    VarDecl *DstVD =
20658
0
        buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
20659
0
                     VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20660
0
    DeclRefExpr *PseudoDstExpr =
20661
0
        buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
20662
    // For arrays generate assignment operation for single element and replace
20663
    // it by the original array element in CodeGen.
20664
0
    ExprResult AssignmentOp =
20665
0
        BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20666
0
                   PseudoSrcExpr);
20667
0
    if (AssignmentOp.isInvalid())
20668
0
      continue;
20669
0
    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
20670
0
                                       /*DiscardedValue*/ false);
20671
0
    if (AssignmentOp.isInvalid())
20672
0
      continue;
20673
20674
0
    DSAStack->addDSA(VD, DE, OMPC_copyin);
20675
0
    Vars.push_back(DE);
20676
0
    SrcExprs.push_back(PseudoSrcExpr);
20677
0
    DstExprs.push_back(PseudoDstExpr);
20678
0
    AssignmentOps.push_back(AssignmentOp.get());
20679
0
  }
20680
20681
0
  if (Vars.empty())
20682
0
    return nullptr;
20683
20684
0
  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
20685
0
                                 SrcExprs, DstExprs, AssignmentOps);
20686
0
}
20687
20688
OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
20689
                                              SourceLocation StartLoc,
20690
                                              SourceLocation LParenLoc,
20691
0
                                              SourceLocation EndLoc) {
20692
0
  SmallVector<Expr *, 8> Vars;
20693
0
  SmallVector<Expr *, 8> SrcExprs;
20694
0
  SmallVector<Expr *, 8> DstExprs;
20695
0
  SmallVector<Expr *, 8> AssignmentOps;
20696
0
  for (Expr *RefExpr : VarList) {
20697
0
    assert(RefExpr && "NULL expr in OpenMP linear clause.");
20698
0
    SourceLocation ELoc;
20699
0
    SourceRange ERange;
20700
0
    Expr *SimpleRefExpr = RefExpr;
20701
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20702
0
    if (Res.second) {
20703
      // It will be analyzed later.
20704
0
      Vars.push_back(RefExpr);
20705
0
      SrcExprs.push_back(nullptr);
20706
0
      DstExprs.push_back(nullptr);
20707
0
      AssignmentOps.push_back(nullptr);
20708
0
    }
20709
0
    ValueDecl *D = Res.first;
20710
0
    if (!D)
20711
0
      continue;
20712
20713
0
    QualType Type = D->getType();
20714
0
    auto *VD = dyn_cast<VarDecl>(D);
20715
20716
    // OpenMP [2.14.4.2, Restrictions, p.2]
20717
    //  A list item that appears in a copyprivate clause may not appear in a
20718
    //  private or firstprivate clause on the single construct.
20719
0
    if (!VD || !DSAStack->isThreadPrivate(VD)) {
20720
0
      DSAStackTy::DSAVarData DVar =
20721
0
          DSAStack->getTopDSA(D, /*FromParent=*/false);
20722
0
      if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20723
0
          DVar.RefExpr) {
20724
0
        Diag(ELoc, diag::err_omp_wrong_dsa)
20725
0
            << getOpenMPClauseName(DVar.CKind)
20726
0
            << getOpenMPClauseName(OMPC_copyprivate);
20727
0
        reportOriginalDsa(*this, DSAStack, D, DVar);
20728
0
        continue;
20729
0
      }
20730
20731
      // OpenMP [2.11.4.2, Restrictions, p.1]
20732
      //  All list items that appear in a copyprivate clause must be either
20733
      //  threadprivate or private in the enclosing context.
20734
0
      if (DVar.CKind == OMPC_unknown) {
20735
0
        DVar = DSAStack->getImplicitDSA(D, false);
20736
0
        if (DVar.CKind == OMPC_shared) {
20737
0
          Diag(ELoc, diag::err_omp_required_access)
20738
0
              << getOpenMPClauseName(OMPC_copyprivate)
20739
0
              << "threadprivate or private in the enclosing context";
20740
0
          reportOriginalDsa(*this, DSAStack, D, DVar);
20741
0
          continue;
20742
0
        }
20743
0
      }
20744
0
    }
20745
20746
    // Variably modified types are not supported.
20747
0
    if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
20748
0
      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20749
0
          << getOpenMPClauseName(OMPC_copyprivate) << Type
20750
0
          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20751
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20752
0
                               VarDecl::DeclarationOnly;
20753
0
      Diag(D->getLocation(),
20754
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20755
0
          << D;
20756
0
      continue;
20757
0
    }
20758
20759
    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20760
    //  A variable of class type (or array thereof) that appears in a
20761
    //  copyin clause requires an accessible, unambiguous copy assignment
20762
    //  operator for the class type.
20763
0
    Type = Context.getBaseElementType(Type.getNonReferenceType())
20764
0
               .getUnqualifiedType();
20765
0
    VarDecl *SrcVD =
20766
0
        buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
20767
0
                     D->hasAttrs() ? &D->getAttrs() : nullptr);
20768
0
    DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
20769
0
    VarDecl *DstVD =
20770
0
        buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
20771
0
                     D->hasAttrs() ? &D->getAttrs() : nullptr);
20772
0
    DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
20773
0
    ExprResult AssignmentOp = BuildBinOp(
20774
0
        DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20775
0
    if (AssignmentOp.isInvalid())
20776
0
      continue;
20777
0
    AssignmentOp =
20778
0
        ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
20779
0
    if (AssignmentOp.isInvalid())
20780
0
      continue;
20781
20782
    // No need to mark vars as copyprivate, they are already threadprivate or
20783
    // implicitly private.
20784
0
    assert(VD || isOpenMPCapturedDecl(D));
20785
0
    Vars.push_back(
20786
0
        VD ? RefExpr->IgnoreParens()
20787
0
           : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
20788
0
    SrcExprs.push_back(PseudoSrcExpr);
20789
0
    DstExprs.push_back(PseudoDstExpr);
20790
0
    AssignmentOps.push_back(AssignmentOp.get());
20791
0
  }
20792
20793
0
  if (Vars.empty())
20794
0
    return nullptr;
20795
20796
0
  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20797
0
                                      Vars, SrcExprs, DstExprs, AssignmentOps);
20798
0
}
20799
20800
OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
20801
                                        SourceLocation StartLoc,
20802
                                        SourceLocation LParenLoc,
20803
0
                                        SourceLocation EndLoc) {
20804
0
  if (VarList.empty())
20805
0
    return nullptr;
20806
20807
0
  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
20808
0
}
20809
20810
/// Tries to find omp_depend_t. type.
20811
static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
20812
0
                           bool Diagnose = true) {
20813
0
  QualType OMPDependT = Stack->getOMPDependT();
20814
0
  if (!OMPDependT.isNull())
20815
0
    return true;
20816
0
  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
20817
0
  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20818
0
  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20819
0
    if (Diagnose)
20820
0
      S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
20821
0
    return false;
20822
0
  }
20823
0
  Stack->setOMPDependT(PT.get());
20824
0
  return true;
20825
0
}
20826
20827
OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
20828
                                         SourceLocation LParenLoc,
20829
0
                                         SourceLocation EndLoc) {
20830
0
  if (!Depobj)
20831
0
    return nullptr;
20832
20833
0
  bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
20834
20835
  // OpenMP 5.0, 2.17.10.1 depobj Construct
20836
  // depobj is an lvalue expression of type omp_depend_t.
20837
0
  if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
20838
0
      !Depobj->isInstantiationDependent() &&
20839
0
      !Depobj->containsUnexpandedParameterPack() &&
20840
0
      (OMPDependTFound &&
20841
0
       !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
20842
0
                                   /*CompareUnqualified=*/true))) {
20843
0
    Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20844
0
        << 0 << Depobj->getType() << Depobj->getSourceRange();
20845
0
  }
20846
20847
0
  if (!Depobj->isLValue()) {
20848
0
    Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20849
0
        << 1 << Depobj->getSourceRange();
20850
0
  }
20851
20852
0
  return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
20853
0
}
20854
20855
namespace {
20856
// Utility struct that gathers the related info for doacross clause.
20857
struct DoacrossDataInfoTy {
20858
  // The list of expressions.
20859
  SmallVector<Expr *, 8> Vars;
20860
  // The OperatorOffset for doacross loop.
20861
  DSAStackTy::OperatorOffsetTy OpsOffs;
20862
  // The depended loop count.
20863
  llvm::APSInt TotalDepCount;
20864
};
20865
} // namespace
20866
static DoacrossDataInfoTy
20867
ProcessOpenMPDoacrossClauseCommon(Sema &SemaRef, bool IsSource,
20868
                                  ArrayRef<Expr *> VarList, DSAStackTy *Stack,
20869
0
                                  SourceLocation EndLoc) {
20870
20871
0
  SmallVector<Expr *, 8> Vars;
20872
0
  DSAStackTy::OperatorOffsetTy OpsOffs;
20873
0
  llvm::APSInt DepCounter(/*BitWidth=*/32);
20874
0
  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20875
20876
0
  if (const Expr *OrderedCountExpr =
20877
0
          Stack->getParentOrderedRegionParam().first) {
20878
0
    TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.Context);
20879
0
    TotalDepCount.setIsUnsigned(/*Val=*/true);
20880
0
  }
20881
20882
0
  for (Expr *RefExpr : VarList) {
20883
0
    assert(RefExpr && "NULL expr in OpenMP doacross clause.");
20884
0
    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20885
      // It will be analyzed later.
20886
0
      Vars.push_back(RefExpr);
20887
0
      continue;
20888
0
    }
20889
20890
0
    SourceLocation ELoc = RefExpr->getExprLoc();
20891
0
    Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20892
0
    if (!IsSource) {
20893
0
      if (Stack->getParentOrderedRegionParam().first &&
20894
0
          DepCounter >= TotalDepCount) {
20895
0
        SemaRef.Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20896
0
        continue;
20897
0
      }
20898
0
      ++DepCounter;
20899
      // OpenMP  [2.13.9, Summary]
20900
      // depend(dependence-type : vec), where dependence-type is:
20901
      // 'sink' and where vec is the iteration vector, which has the form:
20902
      //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
20903
      // where n is the value specified by the ordered clause in the loop
20904
      // directive, xi denotes the loop iteration variable of the i-th nested
20905
      // loop associated with the loop directive, and di is a constant
20906
      // non-negative integer.
20907
0
      if (SemaRef.CurContext->isDependentContext()) {
20908
        // It will be analyzed later.
20909
0
        Vars.push_back(RefExpr);
20910
0
        continue;
20911
0
      }
20912
0
      SimpleExpr = SimpleExpr->IgnoreImplicit();
20913
0
      OverloadedOperatorKind OOK = OO_None;
20914
0
      SourceLocation OOLoc;
20915
0
      Expr *LHS = SimpleExpr;
20916
0
      Expr *RHS = nullptr;
20917
0
      if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20918
0
        OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
20919
0
        OOLoc = BO->getOperatorLoc();
20920
0
        LHS = BO->getLHS()->IgnoreParenImpCasts();
20921
0
        RHS = BO->getRHS()->IgnoreParenImpCasts();
20922
0
      } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20923
0
        OOK = OCE->getOperator();
20924
0
        OOLoc = OCE->getOperatorLoc();
20925
0
        LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20926
0
        RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
20927
0
      } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20928
0
        OOK = MCE->getMethodDecl()
20929
0
                  ->getNameInfo()
20930
0
                  .getName()
20931
0
                  .getCXXOverloadedOperator();
20932
0
        OOLoc = MCE->getCallee()->getExprLoc();
20933
0
        LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
20934
0
        RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20935
0
      }
20936
0
      SourceLocation ELoc;
20937
0
      SourceRange ERange;
20938
0
      auto Res = getPrivateItem(SemaRef, LHS, ELoc, ERange);
20939
0
      if (Res.second) {
20940
        // It will be analyzed later.
20941
0
        Vars.push_back(RefExpr);
20942
0
      }
20943
0
      ValueDecl *D = Res.first;
20944
0
      if (!D)
20945
0
        continue;
20946
20947
0
      if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
20948
0
        SemaRef.Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20949
0
        continue;
20950
0
      }
20951
0
      if (RHS) {
20952
0
        ExprResult RHSRes = SemaRef.VerifyPositiveIntegerConstantInClause(
20953
0
            RHS, OMPC_depend, /*StrictlyPositive=*/false);
20954
0
        if (RHSRes.isInvalid())
20955
0
          continue;
20956
0
      }
20957
0
      if (!SemaRef.CurContext->isDependentContext() &&
20958
0
          Stack->getParentOrderedRegionParam().first &&
20959
0
          DepCounter != Stack->isParentLoopControlVariable(D).first) {
20960
0
        const ValueDecl *VD =
20961
0
            Stack->getParentLoopControlVariable(DepCounter.getZExtValue());
20962
0
        if (VD)
20963
0
          SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20964
0
              << 1 << VD;
20965
0
        else
20966
0
          SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20967
0
              << 0;
20968
0
        continue;
20969
0
      }
20970
0
      OpsOffs.emplace_back(RHS, OOK);
20971
0
    }
20972
0
    Vars.push_back(RefExpr->IgnoreParenImpCasts());
20973
0
  }
20974
0
  if (!SemaRef.CurContext->isDependentContext() && !IsSource &&
20975
0
      TotalDepCount > VarList.size() &&
20976
0
      Stack->getParentOrderedRegionParam().first &&
20977
0
      Stack->getParentLoopControlVariable(VarList.size() + 1)) {
20978
0
    SemaRef.Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
20979
0
        << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1);
20980
0
  }
20981
0
  return {Vars, OpsOffs, TotalDepCount};
20982
0
}
20983
20984
OMPClause *
20985
Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data,
20986
                              Expr *DepModifier, ArrayRef<Expr *> VarList,
20987
                              SourceLocation StartLoc, SourceLocation LParenLoc,
20988
0
                              SourceLocation EndLoc) {
20989
0
  OpenMPDependClauseKind DepKind = Data.DepKind;
20990
0
  SourceLocation DepLoc = Data.DepLoc;
20991
0
  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
20992
0
      DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
20993
0
    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20994
0
        << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20995
0
    return nullptr;
20996
0
  }
20997
0
  if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
20998
0
      DepKind == OMPC_DEPEND_mutexinoutset) {
20999
0
    Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
21000
0
    return nullptr;
21001
0
  }
21002
0
  if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
21003
0
       DSAStack->getCurrentDirective() == OMPD_depobj) &&
21004
0
      (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
21005
0
       DepKind == OMPC_DEPEND_sink ||
21006
0
       ((LangOpts.OpenMP < 50 ||
21007
0
         DSAStack->getCurrentDirective() == OMPD_depobj) &&
21008
0
        DepKind == OMPC_DEPEND_depobj))) {
21009
0
    SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
21010
0
                                       OMPC_DEPEND_outallmemory,
21011
0
                                       OMPC_DEPEND_inoutallmemory};
21012
0
    if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
21013
0
      Except.push_back(OMPC_DEPEND_depobj);
21014
0
    if (LangOpts.OpenMP < 51)
21015
0
      Except.push_back(OMPC_DEPEND_inoutset);
21016
0
    std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
21017
0
                               ? "depend modifier(iterator) or "
21018
0
                               : "";
21019
0
    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
21020
0
        << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
21021
0
                                              /*Last=*/OMPC_DEPEND_unknown,
21022
0
                                              Except)
21023
0
        << getOpenMPClauseName(OMPC_depend);
21024
0
    return nullptr;
21025
0
  }
21026
0
  if (DepModifier &&
21027
0
      (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
21028
0
    Diag(DepModifier->getExprLoc(),
21029
0
         diag::err_omp_depend_sink_source_with_modifier);
21030
0
    return nullptr;
21031
0
  }
21032
0
  if (DepModifier &&
21033
0
      !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
21034
0
    Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
21035
21036
0
  SmallVector<Expr *, 8> Vars;
21037
0
  DSAStackTy::OperatorOffsetTy OpsOffs;
21038
0
  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
21039
21040
0
  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
21041
0
    DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
21042
0
        *this, DepKind == OMPC_DEPEND_source, VarList, DSAStack, EndLoc);
21043
0
    Vars = VarOffset.Vars;
21044
0
    OpsOffs = VarOffset.OpsOffs;
21045
0
    TotalDepCount = VarOffset.TotalDepCount;
21046
0
  } else {
21047
0
    for (Expr *RefExpr : VarList) {
21048
0
      assert(RefExpr && "NULL expr in OpenMP shared clause.");
21049
0
      if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
21050
        // It will be analyzed later.
21051
0
        Vars.push_back(RefExpr);
21052
0
        continue;
21053
0
      }
21054
21055
0
      SourceLocation ELoc = RefExpr->getExprLoc();
21056
0
      Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
21057
0
      if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
21058
0
        bool OMPDependTFound = LangOpts.OpenMP >= 50;
21059
0
        if (OMPDependTFound)
21060
0
          OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
21061
0
                                           DepKind == OMPC_DEPEND_depobj);
21062
0
        if (DepKind == OMPC_DEPEND_depobj) {
21063
          // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
21064
          // List items used in depend clauses with the depobj dependence type
21065
          // must be expressions of the omp_depend_t type.
21066
0
          if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21067
0
              !RefExpr->isInstantiationDependent() &&
21068
0
              !RefExpr->containsUnexpandedParameterPack() &&
21069
0
              (OMPDependTFound &&
21070
0
               !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
21071
0
                                               RefExpr->getType()))) {
21072
0
            Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21073
0
                << 0 << RefExpr->getType() << RefExpr->getSourceRange();
21074
0
            continue;
21075
0
          }
21076
0
          if (!RefExpr->isLValue()) {
21077
0
            Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21078
0
                << 1 << RefExpr->getType() << RefExpr->getSourceRange();
21079
0
            continue;
21080
0
          }
21081
0
        } else {
21082
          // OpenMP 5.0 [2.17.11, Restrictions]
21083
          // List items used in depend clauses cannot be zero-length array
21084
          // sections.
21085
0
          QualType ExprTy = RefExpr->getType().getNonReferenceType();
21086
0
          const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
21087
0
          if (OASE) {
21088
0
            QualType BaseType =
21089
0
                OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
21090
0
            if (BaseType.isNull())
21091
0
              return nullptr;
21092
0
            if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21093
0
              ExprTy = ATy->getElementType();
21094
0
            else
21095
0
              ExprTy = BaseType->getPointeeType();
21096
0
            ExprTy = ExprTy.getNonReferenceType();
21097
0
            const Expr *Length = OASE->getLength();
21098
0
            Expr::EvalResult Result;
21099
0
            if (Length && !Length->isValueDependent() &&
21100
0
                Length->EvaluateAsInt(Result, Context) &&
21101
0
                Result.Val.getInt().isZero()) {
21102
0
              Diag(ELoc,
21103
0
                   diag::err_omp_depend_zero_length_array_section_not_allowed)
21104
0
                  << SimpleExpr->getSourceRange();
21105
0
              continue;
21106
0
            }
21107
0
          }
21108
21109
          // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
21110
          // List items used in depend clauses with the in, out, inout,
21111
          // inoutset, or mutexinoutset dependence types cannot be
21112
          // expressions of the omp_depend_t type.
21113
0
          if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21114
0
              !RefExpr->isInstantiationDependent() &&
21115
0
              !RefExpr->containsUnexpandedParameterPack() &&
21116
0
              (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
21117
0
               (OMPDependTFound && DSAStack->getOMPDependT().getTypePtr() ==
21118
0
                                       ExprTy.getTypePtr()))) {
21119
0
            Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21120
0
                << (LangOpts.OpenMP >= 50 ? 1 : 0)
21121
0
                << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21122
0
            continue;
21123
0
          }
21124
21125
0
          auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
21126
0
          if (ASE && !ASE->getBase()->isTypeDependent() &&
21127
0
              !ASE->getBase()
21128
0
                   ->getType()
21129
0
                   .getNonReferenceType()
21130
0
                   ->isPointerType() &&
21131
0
              !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
21132
0
            Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21133
0
                << (LangOpts.OpenMP >= 50 ? 1 : 0)
21134
0
                << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21135
0
            continue;
21136
0
          }
21137
21138
0
          ExprResult Res;
21139
0
          {
21140
0
            Sema::TentativeAnalysisScope Trap(*this);
21141
0
            Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
21142
0
                                       RefExpr->IgnoreParenImpCasts());
21143
0
          }
21144
0
          if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
21145
0
              !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21146
0
            Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21147
0
                << (LangOpts.OpenMP >= 50 ? 1 : 0)
21148
0
                << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21149
0
            continue;
21150
0
          }
21151
0
        }
21152
0
      }
21153
0
      Vars.push_back(RefExpr->IgnoreParenImpCasts());
21154
0
    }
21155
0
  }
21156
21157
0
  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
21158
0
      DepKind != OMPC_DEPEND_outallmemory &&
21159
0
      DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
21160
0
    return nullptr;
21161
21162
0
  auto *C = OMPDependClause::Create(
21163
0
      Context, StartLoc, LParenLoc, EndLoc,
21164
0
      {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars,
21165
0
      TotalDepCount.getZExtValue());
21166
0
  if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
21167
0
      DSAStack->isParentOrderedRegion())
21168
0
    DSAStack->addDoacrossDependClause(C, OpsOffs);
21169
0
  return C;
21170
0
}
21171
21172
OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
21173
                                         Expr *Device, SourceLocation StartLoc,
21174
                                         SourceLocation LParenLoc,
21175
                                         SourceLocation ModifierLoc,
21176
0
                                         SourceLocation EndLoc) {
21177
0
  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
21178
0
         "Unexpected device modifier in OpenMP < 50.");
21179
21180
0
  bool ErrorFound = false;
21181
0
  if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
21182
0
    std::string Values =
21183
0
        getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
21184
0
    Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
21185
0
        << Values << getOpenMPClauseName(OMPC_device);
21186
0
    ErrorFound = true;
21187
0
  }
21188
21189
0
  Expr *ValExpr = Device;
21190
0
  Stmt *HelperValStmt = nullptr;
21191
21192
  // OpenMP [2.9.1, Restrictions]
21193
  // The device expression must evaluate to a non-negative integer value.
21194
0
  ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
21195
0
                                          /*StrictlyPositive=*/false) ||
21196
0
               ErrorFound;
21197
0
  if (ErrorFound)
21198
0
    return nullptr;
21199
21200
  // OpenMP 5.0 [2.12.5, Restrictions]
21201
  // In case of ancestor device-modifier, a requires directive with
21202
  // the reverse_offload clause must be specified.
21203
0
  if (Modifier == OMPC_DEVICE_ancestor) {
21204
0
    if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
21205
0
      targetDiag(
21206
0
          StartLoc,
21207
0
          diag::err_omp_device_ancestor_without_requires_reverse_offload);
21208
0
      ErrorFound = true;
21209
0
    }
21210
0
  }
21211
21212
0
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
21213
0
  OpenMPDirectiveKind CaptureRegion =
21214
0
      getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
21215
0
  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
21216
0
    ValExpr = MakeFullExpr(ValExpr).get();
21217
0
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21218
0
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21219
0
    HelperValStmt = buildPreInits(Context, Captures);
21220
0
  }
21221
21222
0
  return new (Context)
21223
0
      OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
21224
0
                      LParenLoc, ModifierLoc, EndLoc);
21225
0
}
21226
21227
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
21228
                              DSAStackTy *Stack, QualType QTy,
21229
0
                              bool FullCheck = true) {
21230
0
  if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
21231
0
    return false;
21232
0
  if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
21233
0
      !QTy.isTriviallyCopyableType(SemaRef.Context))
21234
0
    SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
21235
0
  return true;
21236
0
}
21237
21238
/// Return true if it can be proven that the provided array expression
21239
/// (array section or array subscript) does NOT specify the whole size of the
21240
/// array whose base type is \a BaseQTy.
21241
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
21242
                                                        const Expr *E,
21243
0
                                                        QualType BaseQTy) {
21244
0
  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21245
21246
  // If this is an array subscript, it refers to the whole size if the size of
21247
  // the dimension is constant and equals 1. Also, an array section assumes the
21248
  // format of an array subscript if no colon is used.
21249
0
  if (isa<ArraySubscriptExpr>(E) ||
21250
0
      (OASE && OASE->getColonLocFirst().isInvalid())) {
21251
0
    if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
21252
0
      return ATy->getSize().getSExtValue() != 1;
21253
    // Size can't be evaluated statically.
21254
0
    return false;
21255
0
  }
21256
21257
0
  assert(OASE && "Expecting array section if not an array subscript.");
21258
0
  const Expr *LowerBound = OASE->getLowerBound();
21259
0
  const Expr *Length = OASE->getLength();
21260
21261
  // If there is a lower bound that does not evaluates to zero, we are not
21262
  // covering the whole dimension.
21263
0
  if (LowerBound) {
21264
0
    Expr::EvalResult Result;
21265
0
    if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
21266
0
      return false; // Can't get the integer value as a constant.
21267
21268
0
    llvm::APSInt ConstLowerBound = Result.Val.getInt();
21269
0
    if (ConstLowerBound.getSExtValue())
21270
0
      return true;
21271
0
  }
21272
21273
  // If we don't have a length we covering the whole dimension.
21274
0
  if (!Length)
21275
0
    return false;
21276
21277
  // If the base is a pointer, we don't have a way to get the size of the
21278
  // pointee.
21279
0
  if (BaseQTy->isPointerType())
21280
0
    return false;
21281
21282
  // We can only check if the length is the same as the size of the dimension
21283
  // if we have a constant array.
21284
0
  const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
21285
0
  if (!CATy)
21286
0
    return false;
21287
21288
0
  Expr::EvalResult Result;
21289
0
  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21290
0
    return false; // Can't get the integer value as a constant.
21291
21292
0
  llvm::APSInt ConstLength = Result.Val.getInt();
21293
0
  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
21294
0
}
21295
21296
// Return true if it can be proven that the provided array expression (array
21297
// section or array subscript) does NOT specify a single element of the array
21298
// whose base type is \a BaseQTy.
21299
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
21300
                                                        const Expr *E,
21301
0
                                                        QualType BaseQTy) {
21302
0
  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21303
21304
  // An array subscript always refer to a single element. Also, an array section
21305
  // assumes the format of an array subscript if no colon is used.
21306
0
  if (isa<ArraySubscriptExpr>(E) ||
21307
0
      (OASE && OASE->getColonLocFirst().isInvalid()))
21308
0
    return false;
21309
21310
0
  assert(OASE && "Expecting array section if not an array subscript.");
21311
0
  const Expr *Length = OASE->getLength();
21312
21313
  // If we don't have a length we have to check if the array has unitary size
21314
  // for this dimension. Also, we should always expect a length if the base type
21315
  // is pointer.
21316
0
  if (!Length) {
21317
0
    if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
21318
0
      return ATy->getSize().getSExtValue() != 1;
21319
    // We cannot assume anything.
21320
0
    return false;
21321
0
  }
21322
21323
  // Check if the length evaluates to 1.
21324
0
  Expr::EvalResult Result;
21325
0
  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21326
0
    return false; // Can't get the integer value as a constant.
21327
21328
0
  llvm::APSInt ConstLength = Result.Val.getInt();
21329
0
  return ConstLength.getSExtValue() != 1;
21330
0
}
21331
21332
// The base of elements of list in a map clause have to be either:
21333
//  - a reference to variable or field.
21334
//  - a member expression.
21335
//  - an array expression.
21336
//
21337
// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
21338
// reference to 'r'.
21339
//
21340
// If we have:
21341
//
21342
// struct SS {
21343
//   Bla S;
21344
//   foo() {
21345
//     #pragma omp target map (S.Arr[:12]);
21346
//   }
21347
// }
21348
//
21349
// We want to retrieve the member expression 'this->S';
21350
21351
// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
21352
//  If a list item is an array section, it must specify contiguous storage.
21353
//
21354
// For this restriction it is sufficient that we make sure only references
21355
// to variables or fields and array expressions, and that no array sections
21356
// exist except in the rightmost expression (unless they cover the whole
21357
// dimension of the array). E.g. these would be invalid:
21358
//
21359
//   r.ArrS[3:5].Arr[6:7]
21360
//
21361
//   r.ArrS[3:5].x
21362
//
21363
// but these would be valid:
21364
//   r.ArrS[3].Arr[6:7]
21365
//
21366
//   r.ArrS[3].x
21367
namespace {
21368
class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
21369
  Sema &SemaRef;
21370
  OpenMPClauseKind CKind = OMPC_unknown;
21371
  OpenMPDirectiveKind DKind = OMPD_unknown;
21372
  OMPClauseMappableExprCommon::MappableExprComponentList &Components;
21373
  bool IsNonContiguous = false;
21374
  bool NoDiagnose = false;
21375
  const Expr *RelevantExpr = nullptr;
21376
  bool AllowUnitySizeArraySection = true;
21377
  bool AllowWholeSizeArraySection = true;
21378
  bool AllowAnotherPtr = true;
21379
  SourceLocation ELoc;
21380
  SourceRange ERange;
21381
21382
0
  void emitErrorMsg() {
21383
    // If nothing else worked, this is not a valid map clause expression.
21384
0
    if (SemaRef.getLangOpts().OpenMP < 50) {
21385
0
      SemaRef.Diag(ELoc,
21386
0
                   diag::err_omp_expected_named_var_member_or_array_expression)
21387
0
          << ERange;
21388
0
    } else {
21389
0
      SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21390
0
          << getOpenMPClauseName(CKind) << ERange;
21391
0
    }
21392
0
  }
21393
21394
public:
21395
0
  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
21396
0
    if (!isa<VarDecl>(DRE->getDecl())) {
21397
0
      emitErrorMsg();
21398
0
      return false;
21399
0
    }
21400
0
    assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21401
0
    RelevantExpr = DRE;
21402
    // Record the component.
21403
0
    Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
21404
0
    return true;
21405
0
  }
21406
21407
0
  bool VisitMemberExpr(MemberExpr *ME) {
21408
0
    Expr *E = ME;
21409
0
    Expr *BaseE = ME->getBase()->IgnoreParenCasts();
21410
21411
0
    if (isa<CXXThisExpr>(BaseE)) {
21412
0
      assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21413
      // We found a base expression: this->Val.
21414
0
      RelevantExpr = ME;
21415
0
    } else {
21416
0
      E = BaseE;
21417
0
    }
21418
21419
0
    if (!isa<FieldDecl>(ME->getMemberDecl())) {
21420
0
      if (!NoDiagnose) {
21421
0
        SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
21422
0
            << ME->getSourceRange();
21423
0
        return false;
21424
0
      }
21425
0
      if (RelevantExpr)
21426
0
        return false;
21427
0
      return Visit(E);
21428
0
    }
21429
21430
0
    auto *FD = cast<FieldDecl>(ME->getMemberDecl());
21431
21432
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
21433
    //  A bit-field cannot appear in a map clause.
21434
    //
21435
0
    if (FD->isBitField()) {
21436
0
      if (!NoDiagnose) {
21437
0
        SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
21438
0
            << ME->getSourceRange() << getOpenMPClauseName(CKind);
21439
0
        return false;
21440
0
      }
21441
0
      if (RelevantExpr)
21442
0
        return false;
21443
0
      return Visit(E);
21444
0
    }
21445
21446
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21447
    //  If the type of a list item is a reference to a type T then the type
21448
    //  will be considered to be T for all purposes of this clause.
21449
0
    QualType CurType = BaseE->getType().getNonReferenceType();
21450
21451
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
21452
    //  A list item cannot be a variable that is a member of a structure with
21453
    //  a union type.
21454
    //
21455
0
    if (CurType->isUnionType()) {
21456
0
      if (!NoDiagnose) {
21457
0
        SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
21458
0
            << ME->getSourceRange();
21459
0
        return false;
21460
0
      }
21461
0
      return RelevantExpr || Visit(E);
21462
0
    }
21463
21464
    // If we got a member expression, we should not expect any array section
21465
    // before that:
21466
    //
21467
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
21468
    //  If a list item is an element of a structure, only the rightmost symbol
21469
    //  of the variable reference can be an array section.
21470
    //
21471
0
    AllowUnitySizeArraySection = false;
21472
0
    AllowWholeSizeArraySection = false;
21473
21474
    // Record the component.
21475
0
    Components.emplace_back(ME, FD, IsNonContiguous);
21476
0
    return RelevantExpr || Visit(E);
21477
0
  }
21478
21479
0
  bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
21480
0
    Expr *E = AE->getBase()->IgnoreParenImpCasts();
21481
21482
0
    if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
21483
0
      if (!NoDiagnose) {
21484
0
        SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21485
0
            << 0 << AE->getSourceRange();
21486
0
        return false;
21487
0
      }
21488
0
      return RelevantExpr || Visit(E);
21489
0
    }
21490
21491
    // If we got an array subscript that express the whole dimension we
21492
    // can have any array expressions before. If it only expressing part of
21493
    // the dimension, we can only have unitary-size array expressions.
21494
0
    if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
21495
0
      AllowWholeSizeArraySection = false;
21496
21497
0
    if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
21498
0
      Expr::EvalResult Result;
21499
0
      if (!AE->getIdx()->isValueDependent() &&
21500
0
          AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
21501
0
          !Result.Val.getInt().isZero()) {
21502
0
        SemaRef.Diag(AE->getIdx()->getExprLoc(),
21503
0
                     diag::err_omp_invalid_map_this_expr);
21504
0
        SemaRef.Diag(AE->getIdx()->getExprLoc(),
21505
0
                     diag::note_omp_invalid_subscript_on_this_ptr_map);
21506
0
      }
21507
0
      assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21508
0
      RelevantExpr = TE;
21509
0
    }
21510
21511
    // Record the component - we don't have any declaration associated.
21512
0
    Components.emplace_back(AE, nullptr, IsNonContiguous);
21513
21514
0
    return RelevantExpr || Visit(E);
21515
0
  }
21516
21517
0
  bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
21518
    // After OMP 5.0  Array section in reduction clause will be implicitly
21519
    // mapped
21520
0
    assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
21521
0
           "Array sections cannot be implicitly mapped.");
21522
0
    Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21523
0
    QualType CurType =
21524
0
        OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21525
21526
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21527
    //  If the type of a list item is a reference to a type T then the type
21528
    //  will be considered to be T for all purposes of this clause.
21529
0
    if (CurType->isReferenceType())
21530
0
      CurType = CurType->getPointeeType();
21531
21532
0
    bool IsPointer = CurType->isAnyPointerType();
21533
21534
0
    if (!IsPointer && !CurType->isArrayType()) {
21535
0
      SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21536
0
          << 0 << OASE->getSourceRange();
21537
0
      return false;
21538
0
    }
21539
21540
0
    bool NotWhole =
21541
0
        checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
21542
0
    bool NotUnity =
21543
0
        checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
21544
21545
0
    if (AllowWholeSizeArraySection) {
21546
      // Any array section is currently allowed. Allowing a whole size array
21547
      // section implies allowing a unity array section as well.
21548
      //
21549
      // If this array section refers to the whole dimension we can still
21550
      // accept other array sections before this one, except if the base is a
21551
      // pointer. Otherwise, only unitary sections are accepted.
21552
0
      if (NotWhole || IsPointer)
21553
0
        AllowWholeSizeArraySection = false;
21554
0
    } else if (DKind == OMPD_target_update &&
21555
0
               SemaRef.getLangOpts().OpenMP >= 50) {
21556
0
      if (IsPointer && !AllowAnotherPtr)
21557
0
        SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21558
0
            << /*array of unknown bound */ 1;
21559
0
      else
21560
0
        IsNonContiguous = true;
21561
0
    } else if (AllowUnitySizeArraySection && NotUnity) {
21562
      // A unity or whole array section is not allowed and that is not
21563
      // compatible with the properties of the current array section.
21564
0
      if (NoDiagnose)
21565
0
        return false;
21566
0
      SemaRef.Diag(ELoc,
21567
0
                   diag::err_array_section_does_not_specify_contiguous_storage)
21568
0
          << OASE->getSourceRange();
21569
0
      return false;
21570
0
    }
21571
21572
0
    if (IsPointer)
21573
0
      AllowAnotherPtr = false;
21574
21575
0
    if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21576
0
      Expr::EvalResult ResultR;
21577
0
      Expr::EvalResult ResultL;
21578
0
      if (!OASE->getLength()->isValueDependent() &&
21579
0
          OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
21580
0
          !ResultR.Val.getInt().isOne()) {
21581
0
        SemaRef.Diag(OASE->getLength()->getExprLoc(),
21582
0
                     diag::err_omp_invalid_map_this_expr);
21583
0
        SemaRef.Diag(OASE->getLength()->getExprLoc(),
21584
0
                     diag::note_omp_invalid_length_on_this_ptr_mapping);
21585
0
      }
21586
0
      if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
21587
0
          OASE->getLowerBound()->EvaluateAsInt(ResultL,
21588
0
                                               SemaRef.getASTContext()) &&
21589
0
          !ResultL.Val.getInt().isZero()) {
21590
0
        SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21591
0
                     diag::err_omp_invalid_map_this_expr);
21592
0
        SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21593
0
                     diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21594
0
      }
21595
0
      assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21596
0
      RelevantExpr = TE;
21597
0
    }
21598
21599
    // Record the component - we don't have any declaration associated.
21600
0
    Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
21601
0
    return RelevantExpr || Visit(E);
21602
0
  }
21603
0
  bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
21604
0
    Expr *Base = E->getBase();
21605
21606
    // Record the component - we don't have any declaration associated.
21607
0
    Components.emplace_back(E, nullptr, IsNonContiguous);
21608
21609
0
    return Visit(Base->IgnoreParenImpCasts());
21610
0
  }
21611
21612
0
  bool VisitUnaryOperator(UnaryOperator *UO) {
21613
0
    if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
21614
0
        UO->getOpcode() != UO_Deref) {
21615
0
      emitErrorMsg();
21616
0
      return false;
21617
0
    }
21618
0
    if (!RelevantExpr) {
21619
      // Record the component if haven't found base decl.
21620
0
      Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
21621
0
    }
21622
0
    return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
21623
0
  }
21624
0
  bool VisitBinaryOperator(BinaryOperator *BO) {
21625
0
    if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
21626
0
      emitErrorMsg();
21627
0
      return false;
21628
0
    }
21629
21630
    // Pointer arithmetic is the only thing we expect to happen here so after we
21631
    // make sure the binary operator is a pointer type, the only thing we need
21632
    // to do is to visit the subtree that has the same type as root (so that we
21633
    // know the other subtree is just an offset)
21634
0
    Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
21635
0
    Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
21636
0
    Components.emplace_back(BO, nullptr, false);
21637
0
    assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
21638
0
            RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
21639
0
           "Either LHS or RHS have base decl inside");
21640
0
    if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
21641
0
      return RelevantExpr || Visit(LE);
21642
0
    return RelevantExpr || Visit(RE);
21643
0
  }
21644
0
  bool VisitCXXThisExpr(CXXThisExpr *CTE) {
21645
0
    assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21646
0
    RelevantExpr = CTE;
21647
0
    Components.emplace_back(CTE, nullptr, IsNonContiguous);
21648
0
    return true;
21649
0
  }
21650
0
  bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
21651
0
    assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21652
0
    Components.emplace_back(COCE, nullptr, IsNonContiguous);
21653
0
    return true;
21654
0
  }
21655
0
  bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
21656
0
    Expr *Source = E->getSourceExpr();
21657
0
    if (!Source) {
21658
0
      emitErrorMsg();
21659
0
      return false;
21660
0
    }
21661
0
    return Visit(Source);
21662
0
  }
21663
0
  bool VisitStmt(Stmt *) {
21664
0
    emitErrorMsg();
21665
0
    return false;
21666
0
  }
21667
0
  const Expr *getFoundBase() const { return RelevantExpr; }
21668
  explicit MapBaseChecker(
21669
      Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
21670
      OMPClauseMappableExprCommon::MappableExprComponentList &Components,
21671
      bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
21672
      : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21673
0
        NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21674
};
21675
} // namespace
21676
21677
/// Return the expression of the base of the mappable expression or null if it
21678
/// cannot be determined and do all the necessary checks to see if the
21679
/// expression is valid as a standalone mappable expression. In the process,
21680
/// record all the components of the expression.
21681
static const Expr *checkMapClauseExpressionBase(
21682
    Sema &SemaRef, Expr *E,
21683
    OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
21684
0
    OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
21685
0
  SourceLocation ELoc = E->getExprLoc();
21686
0
  SourceRange ERange = E->getSourceRange();
21687
0
  MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21688
0
                         ERange);
21689
0
  if (Checker.Visit(E->IgnoreParens())) {
21690
    // Check if the highest dimension array section has length specified
21691
0
    if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
21692
0
        (CKind == OMPC_to || CKind == OMPC_from)) {
21693
0
      auto CI = CurComponents.rbegin();
21694
0
      auto CE = CurComponents.rend();
21695
0
      for (; CI != CE; ++CI) {
21696
0
        const auto *OASE =
21697
0
            dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21698
0
        if (!OASE)
21699
0
          continue;
21700
0
        if (OASE && OASE->getLength())
21701
0
          break;
21702
0
        SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
21703
0
            << ERange;
21704
0
      }
21705
0
    }
21706
0
    return Checker.getFoundBase();
21707
0
  }
21708
0
  return nullptr;
21709
0
}
21710
21711
// Return true if expression E associated with value VD has conflicts with other
21712
// map information.
21713
static bool checkMapConflicts(
21714
    Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
21715
    bool CurrentRegionOnly,
21716
    OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
21717
0
    OpenMPClauseKind CKind) {
21718
0
  assert(VD && E);
21719
0
  SourceLocation ELoc = E->getExprLoc();
21720
0
  SourceRange ERange = E->getSourceRange();
21721
21722
  // In order to easily check the conflicts we need to match each component of
21723
  // the expression under test with the components of the expressions that are
21724
  // already in the stack.
21725
21726
0
  assert(!CurComponents.empty() && "Map clause expression with no components!");
21727
0
  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21728
0
         "Map clause expression with unexpected base!");
21729
21730
  // Variables to help detecting enclosing problems in data environment nests.
21731
0
  bool IsEnclosedByDataEnvironmentExpr = false;
21732
0
  const Expr *EnclosingExpr = nullptr;
21733
21734
0
  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21735
0
      VD, CurrentRegionOnly,
21736
0
      [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21737
0
       ERange, CKind, &EnclosingExpr,
21738
0
       CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
21739
0
                          StackComponents,
21740
0
                      OpenMPClauseKind Kind) {
21741
0
        if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
21742
0
          return false;
21743
0
        assert(!StackComponents.empty() &&
21744
0
               "Map clause expression with no components!");
21745
0
        assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21746
0
               "Map clause expression with unexpected base!");
21747
0
        (void)VD;
21748
21749
        // The whole expression in the stack.
21750
0
        const Expr *RE = StackComponents.front().getAssociatedExpression();
21751
21752
        // Expressions must start from the same base. Here we detect at which
21753
        // point both expressions diverge from each other and see if we can
21754
        // detect if the memory referred to both expressions is contiguous and
21755
        // do not overlap.
21756
0
        auto CI = CurComponents.rbegin();
21757
0
        auto CE = CurComponents.rend();
21758
0
        auto SI = StackComponents.rbegin();
21759
0
        auto SE = StackComponents.rend();
21760
0
        for (; CI != CE && SI != SE; ++CI, ++SI) {
21761
21762
          // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
21763
          //  At most one list item can be an array item derived from a given
21764
          //  variable in map clauses of the same construct.
21765
0
          if (CurrentRegionOnly &&
21766
0
              (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21767
0
               isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
21768
0
               isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21769
0
              (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21770
0
               isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
21771
0
               isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21772
0
            SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21773
0
                         diag::err_omp_multiple_array_items_in_map_clause)
21774
0
                << CI->getAssociatedExpression()->getSourceRange();
21775
0
            SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21776
0
                         diag::note_used_here)
21777
0
                << SI->getAssociatedExpression()->getSourceRange();
21778
0
            return true;
21779
0
          }
21780
21781
          // Do both expressions have the same kind?
21782
0
          if (CI->getAssociatedExpression()->getStmtClass() !=
21783
0
              SI->getAssociatedExpression()->getStmtClass())
21784
0
            break;
21785
21786
          // Are we dealing with different variables/fields?
21787
0
          if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21788
0
            break;
21789
0
        }
21790
        // Check if the extra components of the expressions in the enclosing
21791
        // data environment are redundant for the current base declaration.
21792
        // If they are, the maps completely overlap, which is legal.
21793
0
        for (; SI != SE; ++SI) {
21794
0
          QualType Type;
21795
0
          if (const auto *ASE =
21796
0
                  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21797
0
            Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21798
0
          } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21799
0
                         SI->getAssociatedExpression())) {
21800
0
            const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21801
0
            Type =
21802
0
                OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21803
0
          } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21804
0
                         SI->getAssociatedExpression())) {
21805
0
            Type = OASE->getBase()->getType()->getPointeeType();
21806
0
          }
21807
0
          if (Type.isNull() || Type->isAnyPointerType() ||
21808
0
              checkArrayExpressionDoesNotReferToWholeSize(
21809
0
                  SemaRef, SI->getAssociatedExpression(), Type))
21810
0
            break;
21811
0
        }
21812
21813
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21814
        //  List items of map clauses in the same construct must not share
21815
        //  original storage.
21816
        //
21817
        // If the expressions are exactly the same or one is a subset of the
21818
        // other, it means they are sharing storage.
21819
0
        if (CI == CE && SI == SE) {
21820
0
          if (CurrentRegionOnly) {
21821
0
            if (CKind == OMPC_map) {
21822
0
              SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21823
0
            } else {
21824
0
              assert(CKind == OMPC_to || CKind == OMPC_from);
21825
0
              SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21826
0
                  << ERange;
21827
0
            }
21828
0
            SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21829
0
                << RE->getSourceRange();
21830
0
            return true;
21831
0
          }
21832
          // If we find the same expression in the enclosing data environment,
21833
          // that is legal.
21834
0
          IsEnclosedByDataEnvironmentExpr = true;
21835
0
          return false;
21836
0
        }
21837
21838
0
        QualType DerivedType =
21839
0
            std::prev(CI)->getAssociatedDeclaration()->getType();
21840
0
        SourceLocation DerivedLoc =
21841
0
            std::prev(CI)->getAssociatedExpression()->getExprLoc();
21842
21843
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21844
        //  If the type of a list item is a reference to a type T then the type
21845
        //  will be considered to be T for all purposes of this clause.
21846
0
        DerivedType = DerivedType.getNonReferenceType();
21847
21848
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
21849
        //  A variable for which the type is pointer and an array section
21850
        //  derived from that variable must not appear as list items of map
21851
        //  clauses of the same construct.
21852
        //
21853
        // Also, cover one of the cases in:
21854
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21855
        //  If any part of the original storage of a list item has corresponding
21856
        //  storage in the device data environment, all of the original storage
21857
        //  must have corresponding storage in the device data environment.
21858
        //
21859
0
        if (DerivedType->isAnyPointerType()) {
21860
0
          if (CI == CE || SI == SE) {
21861
0
            SemaRef.Diag(
21862
0
                DerivedLoc,
21863
0
                diag::err_omp_pointer_mapped_along_with_derived_section)
21864
0
                << DerivedLoc;
21865
0
            SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21866
0
                << RE->getSourceRange();
21867
0
            return true;
21868
0
          }
21869
0
          if (CI->getAssociatedExpression()->getStmtClass() !=
21870
0
                  SI->getAssociatedExpression()->getStmtClass() ||
21871
0
              CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21872
0
                  SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21873
0
            assert(CI != CE && SI != SE);
21874
0
            SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21875
0
                << DerivedLoc;
21876
0
            SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21877
0
                << RE->getSourceRange();
21878
0
            return true;
21879
0
          }
21880
0
        }
21881
21882
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21883
        //  List items of map clauses in the same construct must not share
21884
        //  original storage.
21885
        //
21886
        // An expression is a subset of the other.
21887
0
        if (CurrentRegionOnly && (CI == CE || SI == SE)) {
21888
0
          if (CKind == OMPC_map) {
21889
0
            if (CI != CE || SI != SE) {
21890
              // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
21891
              // a pointer.
21892
0
              auto Begin =
21893
0
                  CI != CE ? CurComponents.begin() : StackComponents.begin();
21894
0
              auto End = CI != CE ? CurComponents.end() : StackComponents.end();
21895
0
              auto It = Begin;
21896
0
              while (It != End && !It->getAssociatedDeclaration())
21897
0
                std::advance(It, 1);
21898
0
              assert(It != End &&
21899
0
                     "Expected at least one component with the declaration.");
21900
0
              if (It != Begin && It->getAssociatedDeclaration()
21901
0
                                     ->getType()
21902
0
                                     .getCanonicalType()
21903
0
                                     ->isAnyPointerType()) {
21904
0
                IsEnclosedByDataEnvironmentExpr = false;
21905
0
                EnclosingExpr = nullptr;
21906
0
                return false;
21907
0
              }
21908
0
            }
21909
0
            SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21910
0
          } else {
21911
0
            assert(CKind == OMPC_to || CKind == OMPC_from);
21912
0
            SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21913
0
                << ERange;
21914
0
          }
21915
0
          SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21916
0
              << RE->getSourceRange();
21917
0
          return true;
21918
0
        }
21919
21920
        // The current expression uses the same base as other expression in the
21921
        // data environment but does not contain it completely.
21922
0
        if (!CurrentRegionOnly && SI != SE)
21923
0
          EnclosingExpr = RE;
21924
21925
        // The current expression is a subset of the expression in the data
21926
        // environment.
21927
0
        IsEnclosedByDataEnvironmentExpr |=
21928
0
            (!CurrentRegionOnly && CI != CE && SI == SE);
21929
21930
0
        return false;
21931
0
      });
21932
21933
0
  if (CurrentRegionOnly)
21934
0
    return FoundError;
21935
21936
  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21937
  //  If any part of the original storage of a list item has corresponding
21938
  //  storage in the device data environment, all of the original storage must
21939
  //  have corresponding storage in the device data environment.
21940
  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
21941
  //  If a list item is an element of a structure, and a different element of
21942
  //  the structure has a corresponding list item in the device data environment
21943
  //  prior to a task encountering the construct associated with the map clause,
21944
  //  then the list item must also have a corresponding list item in the device
21945
  //  data environment prior to the task encountering the construct.
21946
  //
21947
0
  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
21948
0
    SemaRef.Diag(ELoc,
21949
0
                 diag::err_omp_original_storage_is_shared_and_does_not_contain)
21950
0
        << ERange;
21951
0
    SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
21952
0
        << EnclosingExpr->getSourceRange();
21953
0
    return true;
21954
0
  }
21955
21956
0
  return FoundError;
21957
0
}
21958
21959
// Look up the user-defined mapper given the mapper name and mapped type, and
21960
// build a reference to it.
21961
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
21962
                                            CXXScopeSpec &MapperIdScopeSpec,
21963
                                            const DeclarationNameInfo &MapperId,
21964
                                            QualType Type,
21965
0
                                            Expr *UnresolvedMapper) {
21966
0
  if (MapperIdScopeSpec.isInvalid())
21967
0
    return ExprError();
21968
  // Get the actual type for the array type.
21969
0
  if (Type->isArrayType()) {
21970
0
    assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
21971
0
    Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
21972
0
  }
21973
  // Find all user-defined mappers with the given MapperId.
21974
0
  SmallVector<UnresolvedSet<8>, 4> Lookups;
21975
0
  LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
21976
0
  Lookup.suppressDiagnostics();
21977
0
  if (S) {
21978
0
    while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
21979
0
      NamedDecl *D = Lookup.getRepresentativeDecl();
21980
0
      while (S && !S->isDeclScope(D))
21981
0
        S = S->getParent();
21982
0
      if (S)
21983
0
        S = S->getParent();
21984
0
      Lookups.emplace_back();
21985
0
      Lookups.back().append(Lookup.begin(), Lookup.end());
21986
0
      Lookup.clear();
21987
0
    }
21988
0
  } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21989
    // Extract the user-defined mappers with the given MapperId.
21990
0
    Lookups.push_back(UnresolvedSet<8>());
21991
0
    for (NamedDecl *D : ULE->decls()) {
21992
0
      auto *DMD = cast<OMPDeclareMapperDecl>(D);
21993
0
      assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
21994
0
      Lookups.back().addDecl(DMD);
21995
0
    }
21996
0
  }
21997
  // Defer the lookup for dependent types. The results will be passed through
21998
  // UnresolvedMapper on instantiation.
21999
0
  if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
22000
0
      Type->isInstantiationDependentType() ||
22001
0
      Type->containsUnexpandedParameterPack() ||
22002
0
      filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
22003
0
        return !D->isInvalidDecl() &&
22004
0
               (D->getType()->isDependentType() ||
22005
0
                D->getType()->isInstantiationDependentType() ||
22006
0
                D->getType()->containsUnexpandedParameterPack());
22007
0
      })) {
22008
0
    UnresolvedSet<8> URS;
22009
0
    for (const UnresolvedSet<8> &Set : Lookups) {
22010
0
      if (Set.empty())
22011
0
        continue;
22012
0
      URS.append(Set.begin(), Set.end());
22013
0
    }
22014
0
    return UnresolvedLookupExpr::Create(
22015
0
        SemaRef.Context, /*NamingClass=*/nullptr,
22016
0
        MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
22017
0
        /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
22018
0
  }
22019
0
  SourceLocation Loc = MapperId.getLoc();
22020
  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22021
  //  The type must be of struct, union or class type in C and C++
22022
0
  if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
22023
0
      (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
22024
0
    SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
22025
0
    return ExprError();
22026
0
  }
22027
  // Perform argument dependent lookup.
22028
0
  if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
22029
0
    argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
22030
  // Return the first user-defined mapper with the desired type.
22031
0
  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22032
0
          Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
22033
0
            if (!D->isInvalidDecl() &&
22034
0
                SemaRef.Context.hasSameType(D->getType(), Type))
22035
0
              return D;
22036
0
            return nullptr;
22037
0
          }))
22038
0
    return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
22039
  // Find the first user-defined mapper with a type derived from the desired
22040
  // type.
22041
0
  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22042
0
          Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
22043
0
            if (!D->isInvalidDecl() &&
22044
0
                SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
22045
0
                !Type.isMoreQualifiedThan(D->getType()))
22046
0
              return D;
22047
0
            return nullptr;
22048
0
          })) {
22049
0
    CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
22050
0
                       /*DetectVirtual=*/false);
22051
0
    if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
22052
0
      if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
22053
0
              VD->getType().getUnqualifiedType()))) {
22054
0
        if (SemaRef.CheckBaseClassAccess(
22055
0
                Loc, VD->getType(), Type, Paths.front(),
22056
0
                /*DiagID=*/0) != Sema::AR_inaccessible) {
22057
0
          return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
22058
0
        }
22059
0
      }
22060
0
    }
22061
0
  }
22062
  // Report error if a mapper is specified, but cannot be found.
22063
0
  if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
22064
0
    SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
22065
0
        << Type << MapperId.getName();
22066
0
    return ExprError();
22067
0
  }
22068
0
  return ExprEmpty();
22069
0
}
22070
22071
namespace {
22072
// Utility struct that gathers all the related lists associated with a mappable
22073
// expression.
22074
struct MappableVarListInfo {
22075
  // The list of expressions.
22076
  ArrayRef<Expr *> VarList;
22077
  // The list of processed expressions.
22078
  SmallVector<Expr *, 16> ProcessedVarList;
22079
  // The mappble components for each expression.
22080
  OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
22081
  // The base declaration of the variable.
22082
  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
22083
  // The reference to the user-defined mapper associated with every expression.
22084
  SmallVector<Expr *, 16> UDMapperList;
22085
22086
0
  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
22087
    // We have a list of components and base declarations for each entry in the
22088
    // variable list.
22089
0
    VarComponents.reserve(VarList.size());
22090
0
    VarBaseDeclarations.reserve(VarList.size());
22091
0
  }
22092
};
22093
} // namespace
22094
22095
// Check the validity of the provided variable list for the provided clause kind
22096
// \a CKind. In the check process the valid expressions, mappable expression
22097
// components, variables, and user-defined mappers are extracted and used to
22098
// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
22099
// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
22100
// and \a MapperId are expected to be valid if the clause kind is 'map'.
22101
static void checkMappableExpressionList(
22102
    Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
22103
    MappableVarListInfo &MVLI, SourceLocation StartLoc,
22104
    CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
22105
    ArrayRef<Expr *> UnresolvedMappers,
22106
    OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
22107
    ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt,
22108
0
    bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
22109
  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
22110
0
  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
22111
0
         "Unexpected clause kind with mappable expressions!");
22112
22113
  // If the identifier of user-defined mapper is not specified, it is "default".
22114
  // We do not change the actual name in this clause to distinguish whether a
22115
  // mapper is specified explicitly, i.e., it is not explicitly specified when
22116
  // MapperId.getName() is empty.
22117
0
  if (!MapperId.getName() || MapperId.getName().isEmpty()) {
22118
0
    auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
22119
0
    MapperId.setName(DeclNames.getIdentifier(
22120
0
        &SemaRef.getASTContext().Idents.get("default")));
22121
0
    MapperId.setLoc(StartLoc);
22122
0
  }
22123
22124
  // Iterators to find the current unresolved mapper expression.
22125
0
  auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
22126
0
  bool UpdateUMIt = false;
22127
0
  Expr *UnresolvedMapper = nullptr;
22128
22129
0
  bool HasHoldModifier =
22130
0
      llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
22131
22132
  // Keep track of the mappable components and base declarations in this clause.
22133
  // Each entry in the list is going to have a list of components associated. We
22134
  // record each set of the components so that we can build the clause later on.
22135
  // In the end we should have the same amount of declarations and component
22136
  // lists.
22137
22138
0
  for (Expr *RE : MVLI.VarList) {
22139
0
    assert(RE && "Null expr in omp to/from/map clause");
22140
0
    SourceLocation ELoc = RE->getExprLoc();
22141
22142
    // Find the current unresolved mapper expression.
22143
0
    if (UpdateUMIt && UMIt != UMEnd) {
22144
0
      UMIt++;
22145
0
      assert(
22146
0
          UMIt != UMEnd &&
22147
0
          "Expect the size of UnresolvedMappers to match with that of VarList");
22148
0
    }
22149
0
    UpdateUMIt = true;
22150
0
    if (UMIt != UMEnd)
22151
0
      UnresolvedMapper = *UMIt;
22152
22153
0
    const Expr *VE = RE->IgnoreParenLValueCasts();
22154
22155
0
    if (VE->isValueDependent() || VE->isTypeDependent() ||
22156
0
        VE->isInstantiationDependent() ||
22157
0
        VE->containsUnexpandedParameterPack()) {
22158
      // Try to find the associated user-defined mapper.
22159
0
      ExprResult ER = buildUserDefinedMapperRef(
22160
0
          SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22161
0
          VE->getType().getCanonicalType(), UnresolvedMapper);
22162
0
      if (ER.isInvalid())
22163
0
        continue;
22164
0
      MVLI.UDMapperList.push_back(ER.get());
22165
      // We can only analyze this information once the missing information is
22166
      // resolved.
22167
0
      MVLI.ProcessedVarList.push_back(RE);
22168
0
      continue;
22169
0
    }
22170
22171
0
    Expr *SimpleExpr = RE->IgnoreParenCasts();
22172
22173
0
    if (!RE->isLValue()) {
22174
0
      if (SemaRef.getLangOpts().OpenMP < 50) {
22175
0
        SemaRef.Diag(
22176
0
            ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
22177
0
            << RE->getSourceRange();
22178
0
      } else {
22179
0
        SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
22180
0
            << getOpenMPClauseName(CKind) << RE->getSourceRange();
22181
0
      }
22182
0
      continue;
22183
0
    }
22184
22185
0
    OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
22186
0
    ValueDecl *CurDeclaration = nullptr;
22187
22188
    // Obtain the array or member expression bases if required. Also, fill the
22189
    // components array with all the components identified in the process.
22190
0
    const Expr *BE =
22191
0
        checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
22192
0
                                     DSAS->getCurrentDirective(), NoDiagnose);
22193
0
    if (!BE)
22194
0
      continue;
22195
22196
0
    assert(!CurComponents.empty() &&
22197
0
           "Invalid mappable expression information.");
22198
22199
0
    if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
22200
      // Add store "this" pointer to class in DSAStackTy for future checking
22201
0
      DSAS->addMappedClassesQualTypes(TE->getType());
22202
      // Try to find the associated user-defined mapper.
22203
0
      ExprResult ER = buildUserDefinedMapperRef(
22204
0
          SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22205
0
          VE->getType().getCanonicalType(), UnresolvedMapper);
22206
0
      if (ER.isInvalid())
22207
0
        continue;
22208
0
      MVLI.UDMapperList.push_back(ER.get());
22209
      // Skip restriction checking for variable or field declarations
22210
0
      MVLI.ProcessedVarList.push_back(RE);
22211
0
      MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22212
0
      MVLI.VarComponents.back().append(CurComponents.begin(),
22213
0
                                       CurComponents.end());
22214
0
      MVLI.VarBaseDeclarations.push_back(nullptr);
22215
0
      continue;
22216
0
    }
22217
22218
    // For the following checks, we rely on the base declaration which is
22219
    // expected to be associated with the last component. The declaration is
22220
    // expected to be a variable or a field (if 'this' is being mapped).
22221
0
    CurDeclaration = CurComponents.back().getAssociatedDeclaration();
22222
0
    assert(CurDeclaration && "Null decl on map clause.");
22223
0
    assert(
22224
0
        CurDeclaration->isCanonicalDecl() &&
22225
0
        "Expecting components to have associated only canonical declarations.");
22226
22227
0
    auto *VD = dyn_cast<VarDecl>(CurDeclaration);
22228
0
    const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
22229
22230
0
    assert((VD || FD) && "Only variables or fields are expected here!");
22231
0
    (void)FD;
22232
22233
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
22234
    // threadprivate variables cannot appear in a map clause.
22235
    // OpenMP 4.5 [2.10.5, target update Construct]
22236
    // threadprivate variables cannot appear in a from clause.
22237
0
    if (VD && DSAS->isThreadPrivate(VD)) {
22238
0
      if (NoDiagnose)
22239
0
        continue;
22240
0
      DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
22241
0
      SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
22242
0
          << getOpenMPClauseName(CKind);
22243
0
      reportOriginalDsa(SemaRef, DSAS, VD, DVar);
22244
0
      continue;
22245
0
    }
22246
22247
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
22248
    //  A list item cannot appear in both a map clause and a data-sharing
22249
    //  attribute clause on the same construct.
22250
22251
    // Check conflicts with other map clause expressions. We check the conflicts
22252
    // with the current construct separately from the enclosing data
22253
    // environment, because the restrictions are different. We only have to
22254
    // check conflicts across regions for the map clauses.
22255
0
    if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
22256
0
                          /*CurrentRegionOnly=*/true, CurComponents, CKind))
22257
0
      break;
22258
0
    if (CKind == OMPC_map &&
22259
0
        (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
22260
0
        checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
22261
0
                          /*CurrentRegionOnly=*/false, CurComponents, CKind))
22262
0
      break;
22263
22264
    // OpenMP 4.5 [2.10.5, target update Construct]
22265
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
22266
    //  If the type of a list item is a reference to a type T then the type will
22267
    //  be considered to be T for all purposes of this clause.
22268
0
    auto I = llvm::find_if(
22269
0
        CurComponents,
22270
0
        [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
22271
0
          return MC.getAssociatedDeclaration();
22272
0
        });
22273
0
    assert(I != CurComponents.end() && "Null decl on map clause.");
22274
0
    (void)I;
22275
0
    QualType Type;
22276
0
    auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
22277
0
    auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
22278
0
    auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
22279
0
    if (ASE) {
22280
0
      Type = ASE->getType().getNonReferenceType();
22281
0
    } else if (OASE) {
22282
0
      QualType BaseType =
22283
0
          OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
22284
0
      if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
22285
0
        Type = ATy->getElementType();
22286
0
      else
22287
0
        Type = BaseType->getPointeeType();
22288
0
      Type = Type.getNonReferenceType();
22289
0
    } else if (OAShE) {
22290
0
      Type = OAShE->getBase()->getType()->getPointeeType();
22291
0
    } else {
22292
0
      Type = VE->getType();
22293
0
    }
22294
22295
    // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
22296
    // A list item in a to or from clause must have a mappable type.
22297
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
22298
    //  A list item must have a mappable type.
22299
0
    if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
22300
0
                           DSAS, Type, /*FullCheck=*/true))
22301
0
      continue;
22302
22303
0
    if (CKind == OMPC_map) {
22304
      // target enter data
22305
      // OpenMP [2.10.2, Restrictions, p. 99]
22306
      // A map-type must be specified in all map clauses and must be either
22307
      // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if
22308
      // no map type is present.
22309
0
      OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
22310
0
      if (DKind == OMPD_target_enter_data &&
22311
0
          !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
22312
0
            SemaRef.getLangOpts().OpenMP >= 52)) {
22313
0
        SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22314
0
            << (IsMapTypeImplicit ? 1 : 0)
22315
0
            << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22316
0
            << getOpenMPDirectiveName(DKind);
22317
0
        continue;
22318
0
      }
22319
22320
      // target exit_data
22321
      // OpenMP [2.10.3, Restrictions, p. 102]
22322
      // A map-type must be specified in all map clauses and must be either
22323
      // from, release, or delete. Starting with OpenMP 5.2 the default map
22324
      // type is `from` if no map type is present.
22325
0
      if (DKind == OMPD_target_exit_data &&
22326
0
          !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
22327
0
            MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) {
22328
0
        SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22329
0
            << (IsMapTypeImplicit ? 1 : 0)
22330
0
            << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22331
0
            << getOpenMPDirectiveName(DKind);
22332
0
        continue;
22333
0
      }
22334
22335
      // The 'ompx_hold' modifier is specifically intended to be used on a
22336
      // 'target' or 'target data' directive to prevent data from being unmapped
22337
      // during the associated statement.  It is not permitted on a 'target
22338
      // enter data' or 'target exit data' directive, which have no associated
22339
      // statement.
22340
0
      if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
22341
0
          HasHoldModifier) {
22342
0
        SemaRef.Diag(StartLoc,
22343
0
                     diag::err_omp_invalid_map_type_modifier_for_directive)
22344
0
            << getOpenMPSimpleClauseTypeName(OMPC_map,
22345
0
                                             OMPC_MAP_MODIFIER_ompx_hold)
22346
0
            << getOpenMPDirectiveName(DKind);
22347
0
        continue;
22348
0
      }
22349
22350
      // target, target data
22351
      // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
22352
      // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
22353
      // A map-type in a map clause must be to, from, tofrom or alloc
22354
0
      if ((DKind == OMPD_target_data ||
22355
0
           isOpenMPTargetExecutionDirective(DKind)) &&
22356
0
          !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
22357
0
            MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
22358
0
        SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22359
0
            << (IsMapTypeImplicit ? 1 : 0)
22360
0
            << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22361
0
            << getOpenMPDirectiveName(DKind);
22362
0
        continue;
22363
0
      }
22364
22365
      // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
22366
      // A list item cannot appear in both a map clause and a data-sharing
22367
      // attribute clause on the same construct
22368
      //
22369
      // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
22370
      // A list item cannot appear in both a map clause and a data-sharing
22371
      // attribute clause on the same construct unless the construct is a
22372
      // combined construct.
22373
0
      if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
22374
0
                  isOpenMPTargetExecutionDirective(DKind)) ||
22375
0
                 DKind == OMPD_target)) {
22376
0
        DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
22377
0
        if (isOpenMPPrivate(DVar.CKind)) {
22378
0
          SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22379
0
              << getOpenMPClauseName(DVar.CKind)
22380
0
              << getOpenMPClauseName(OMPC_map)
22381
0
              << getOpenMPDirectiveName(DSAS->getCurrentDirective());
22382
0
          reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
22383
0
          continue;
22384
0
        }
22385
0
      }
22386
0
    }
22387
22388
    // Try to find the associated user-defined mapper.
22389
0
    ExprResult ER = buildUserDefinedMapperRef(
22390
0
        SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22391
0
        Type.getCanonicalType(), UnresolvedMapper);
22392
0
    if (ER.isInvalid())
22393
0
      continue;
22394
0
    MVLI.UDMapperList.push_back(ER.get());
22395
22396
    // Save the current expression.
22397
0
    MVLI.ProcessedVarList.push_back(RE);
22398
22399
    // Store the components in the stack so that they can be used to check
22400
    // against other clauses later on.
22401
0
    DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
22402
0
                                          /*WhereFoundClauseKind=*/OMPC_map);
22403
22404
    // Save the components and declaration to create the clause. For purposes of
22405
    // the clause creation, any component list that has base 'this' uses
22406
    // null as base declaration.
22407
0
    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22408
0
    MVLI.VarComponents.back().append(CurComponents.begin(),
22409
0
                                     CurComponents.end());
22410
0
    MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
22411
0
                                                           : CurDeclaration);
22412
0
  }
22413
0
}
22414
22415
OMPClause *Sema::ActOnOpenMPMapClause(
22416
    Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
22417
    ArrayRef<SourceLocation> MapTypeModifiersLoc,
22418
    CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22419
    OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
22420
    SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22421
    const OMPVarListLocTy &Locs, bool NoDiagnose,
22422
0
    ArrayRef<Expr *> UnresolvedMappers) {
22423
0
  OpenMPMapModifierKind Modifiers[] = {
22424
0
      OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22425
0
      OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22426
0
      OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
22427
0
  SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
22428
22429
0
  if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType(
22430
0
                              BuiltinType::OMPIterator))
22431
0
    Diag(IteratorModifier->getExprLoc(),
22432
0
         diag::err_omp_map_modifier_not_iterator);
22433
22434
  // Process map-type-modifiers, flag errors for duplicate modifiers.
22435
0
  unsigned Count = 0;
22436
0
  for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
22437
0
    if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
22438
0
        llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
22439
0
      Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
22440
0
      continue;
22441
0
    }
22442
0
    assert(Count < NumberOfOMPMapClauseModifiers &&
22443
0
           "Modifiers exceed the allowed number of map type modifiers");
22444
0
    Modifiers[Count] = MapTypeModifiers[I];
22445
0
    ModifiersLoc[Count] = MapTypeModifiersLoc[I];
22446
0
    ++Count;
22447
0
  }
22448
22449
0
  MappableVarListInfo MVLI(VarList);
22450
0
  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
22451
0
                              MapperIdScopeSpec, MapperId, UnresolvedMappers,
22452
0
                              MapType, Modifiers, IsMapTypeImplicit,
22453
0
                              NoDiagnose);
22454
22455
  // We need to produce a map clause even if we don't have variables so that
22456
  // other diagnostics related with non-existing map clauses are accurate.
22457
0
  return OMPMapClause::Create(
22458
0
      Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22459
0
      MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
22460
0
      ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(Context), MapperId,
22461
0
      MapType, IsMapTypeImplicit, MapLoc);
22462
0
}
22463
22464
QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
22465
0
                                               TypeResult ParsedType) {
22466
0
  assert(ParsedType.isUsable());
22467
22468
0
  QualType ReductionType = GetTypeFromParser(ParsedType.get());
22469
0
  if (ReductionType.isNull())
22470
0
    return QualType();
22471
22472
  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
22473
  // A type name in a declare reduction directive cannot be a function type, an
22474
  // array type, a reference type, or a type qualified with const, volatile or
22475
  // restrict.
22476
0
  if (ReductionType.hasQualifiers()) {
22477
0
    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
22478
0
    return QualType();
22479
0
  }
22480
22481
0
  if (ReductionType->isFunctionType()) {
22482
0
    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
22483
0
    return QualType();
22484
0
  }
22485
0
  if (ReductionType->isReferenceType()) {
22486
0
    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
22487
0
    return QualType();
22488
0
  }
22489
0
  if (ReductionType->isArrayType()) {
22490
0
    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22491
0
    return QualType();
22492
0
  }
22493
0
  return ReductionType;
22494
0
}
22495
22496
Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
22497
    Scope *S, DeclContext *DC, DeclarationName Name,
22498
    ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22499
0
    AccessSpecifier AS, Decl *PrevDeclInScope) {
22500
0
  SmallVector<Decl *, 8> Decls;
22501
0
  Decls.reserve(ReductionTypes.size());
22502
22503
0
  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
22504
0
                      forRedeclarationInCurContext());
22505
  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
22506
  // A reduction-identifier may not be re-declared in the current scope for the
22507
  // same type or for a type that is compatible according to the base language
22508
  // rules.
22509
0
  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22510
0
  OMPDeclareReductionDecl *PrevDRD = nullptr;
22511
0
  bool InCompoundScope = true;
22512
0
  if (S != nullptr) {
22513
    // Find previous declaration with the same name not referenced in other
22514
    // declarations.
22515
0
    FunctionScopeInfo *ParentFn = getEnclosingFunction();
22516
0
    InCompoundScope =
22517
0
        (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22518
0
    LookupName(Lookup, S);
22519
0
    FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22520
0
                         /*AllowInlineNamespace=*/false);
22521
0
    llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22522
0
    LookupResult::Filter Filter = Lookup.makeFilter();
22523
0
    while (Filter.hasNext()) {
22524
0
      auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22525
0
      if (InCompoundScope) {
22526
0
        auto I = UsedAsPrevious.find(PrevDecl);
22527
0
        if (I == UsedAsPrevious.end())
22528
0
          UsedAsPrevious[PrevDecl] = false;
22529
0
        if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
22530
0
          UsedAsPrevious[D] = true;
22531
0
      }
22532
0
      PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22533
0
          PrevDecl->getLocation();
22534
0
    }
22535
0
    Filter.done();
22536
0
    if (InCompoundScope) {
22537
0
      for (const auto &PrevData : UsedAsPrevious) {
22538
0
        if (!PrevData.second) {
22539
0
          PrevDRD = PrevData.first;
22540
0
          break;
22541
0
        }
22542
0
      }
22543
0
    }
22544
0
  } else if (PrevDeclInScope != nullptr) {
22545
0
    auto *PrevDRDInScope = PrevDRD =
22546
0
        cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22547
0
    do {
22548
0
      PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22549
0
          PrevDRDInScope->getLocation();
22550
0
      PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22551
0
    } while (PrevDRDInScope != nullptr);
22552
0
  }
22553
0
  for (const auto &TyData : ReductionTypes) {
22554
0
    const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22555
0
    bool Invalid = false;
22556
0
    if (I != PreviousRedeclTypes.end()) {
22557
0
      Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22558
0
          << TyData.first;
22559
0
      Diag(I->second, diag::note_previous_definition);
22560
0
      Invalid = true;
22561
0
    }
22562
0
    PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22563
0
    auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
22564
0
                                                Name, TyData.first, PrevDRD);
22565
0
    DC->addDecl(DRD);
22566
0
    DRD->setAccess(AS);
22567
0
    Decls.push_back(DRD);
22568
0
    if (Invalid)
22569
0
      DRD->setInvalidDecl();
22570
0
    else
22571
0
      PrevDRD = DRD;
22572
0
  }
22573
22574
0
  return DeclGroupPtrTy::make(
22575
0
      DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
22576
0
}
22577
22578
0
void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
22579
0
  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22580
22581
  // Enter new function scope.
22582
0
  PushFunctionScope();
22583
0
  setFunctionHasBranchProtectedScope();
22584
0
  getCurFunction()->setHasOMPDeclareReductionCombiner();
22585
22586
0
  if (S != nullptr)
22587
0
    PushDeclContext(S, DRD);
22588
0
  else
22589
0
    CurContext = DRD;
22590
22591
0
  PushExpressionEvaluationContext(
22592
0
      ExpressionEvaluationContext::PotentiallyEvaluated);
22593
22594
0
  QualType ReductionType = DRD->getType();
22595
  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
22596
  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
22597
  // uses semantics of argument handles by value, but it should be passed by
22598
  // reference. C lang does not support references, so pass all parameters as
22599
  // pointers.
22600
  // Create 'T omp_in;' variable.
22601
0
  VarDecl *OmpInParm =
22602
0
      buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
22603
  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
22604
  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
22605
  // uses semantics of argument handles by value, but it should be passed by
22606
  // reference. C lang does not support references, so pass all parameters as
22607
  // pointers.
22608
  // Create 'T omp_out;' variable.
22609
0
  VarDecl *OmpOutParm =
22610
0
      buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
22611
0
  if (S != nullptr) {
22612
0
    PushOnScopeChains(OmpInParm, S);
22613
0
    PushOnScopeChains(OmpOutParm, S);
22614
0
  } else {
22615
0
    DRD->addDecl(OmpInParm);
22616
0
    DRD->addDecl(OmpOutParm);
22617
0
  }
22618
0
  Expr *InE =
22619
0
      ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
22620
0
  Expr *OutE =
22621
0
      ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
22622
0
  DRD->setCombinerData(InE, OutE);
22623
0
}
22624
22625
0
void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
22626
0
  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22627
0
  DiscardCleanupsInEvaluationContext();
22628
0
  PopExpressionEvaluationContext();
22629
22630
0
  PopDeclContext();
22631
0
  PopFunctionScopeInfo();
22632
22633
0
  if (Combiner != nullptr)
22634
0
    DRD->setCombiner(Combiner);
22635
0
  else
22636
0
    DRD->setInvalidDecl();
22637
0
}
22638
22639
0
VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
22640
0
  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22641
22642
  // Enter new function scope.
22643
0
  PushFunctionScope();
22644
0
  setFunctionHasBranchProtectedScope();
22645
22646
0
  if (S != nullptr)
22647
0
    PushDeclContext(S, DRD);
22648
0
  else
22649
0
    CurContext = DRD;
22650
22651
0
  PushExpressionEvaluationContext(
22652
0
      ExpressionEvaluationContext::PotentiallyEvaluated);
22653
22654
0
  QualType ReductionType = DRD->getType();
22655
  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
22656
  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
22657
  // uses semantics of argument handles by value, but it should be passed by
22658
  // reference. C lang does not support references, so pass all parameters as
22659
  // pointers.
22660
  // Create 'T omp_priv;' variable.
22661
0
  VarDecl *OmpPrivParm =
22662
0
      buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
22663
  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
22664
  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
22665
  // uses semantics of argument handles by value, but it should be passed by
22666
  // reference. C lang does not support references, so pass all parameters as
22667
  // pointers.
22668
  // Create 'T omp_orig;' variable.
22669
0
  VarDecl *OmpOrigParm =
22670
0
      buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
22671
0
  if (S != nullptr) {
22672
0
    PushOnScopeChains(OmpPrivParm, S);
22673
0
    PushOnScopeChains(OmpOrigParm, S);
22674
0
  } else {
22675
0
    DRD->addDecl(OmpPrivParm);
22676
0
    DRD->addDecl(OmpOrigParm);
22677
0
  }
22678
0
  Expr *OrigE =
22679
0
      ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
22680
0
  Expr *PrivE =
22681
0
      ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
22682
0
  DRD->setInitializerData(OrigE, PrivE);
22683
0
  return OmpPrivParm;
22684
0
}
22685
22686
void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
22687
0
                                                     VarDecl *OmpPrivParm) {
22688
0
  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22689
0
  DiscardCleanupsInEvaluationContext();
22690
0
  PopExpressionEvaluationContext();
22691
22692
0
  PopDeclContext();
22693
0
  PopFunctionScopeInfo();
22694
22695
0
  if (Initializer != nullptr) {
22696
0
    DRD->setInitializer(Initializer, OMPDeclareReductionInitKind::Call);
22697
0
  } else if (OmpPrivParm->hasInit()) {
22698
0
    DRD->setInitializer(OmpPrivParm->getInit(),
22699
0
                        OmpPrivParm->isDirectInit()
22700
0
                            ? OMPDeclareReductionInitKind::Direct
22701
0
                            : OMPDeclareReductionInitKind::Copy);
22702
0
  } else {
22703
0
    DRD->setInvalidDecl();
22704
0
  }
22705
0
}
22706
22707
Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
22708
0
    Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
22709
0
  for (Decl *D : DeclReductions.get()) {
22710
0
    if (IsValid) {
22711
0
      if (S)
22712
0
        PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
22713
0
                          /*AddToContext=*/false);
22714
0
    } else {
22715
0
      D->setInvalidDecl();
22716
0
    }
22717
0
  }
22718
0
  return DeclReductions;
22719
0
}
22720
22721
0
TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
22722
0
  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
22723
0
  QualType T = TInfo->getType();
22724
0
  if (D.isInvalidType())
22725
0
    return true;
22726
22727
0
  if (getLangOpts().CPlusPlus) {
22728
    // Check that there are no default arguments (C++ only).
22729
0
    CheckExtraCXXDefaultArguments(D);
22730
0
  }
22731
22732
0
  return CreateParsedType(T, TInfo);
22733
0
}
22734
22735
QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
22736
0
                                            TypeResult ParsedType) {
22737
0
  assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
22738
22739
0
  QualType MapperType = GetTypeFromParser(ParsedType.get());
22740
0
  assert(!MapperType.isNull() && "Expect valid mapper type");
22741
22742
  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22743
  //  The type must be of struct, union or class type in C and C++
22744
0
  if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
22745
0
    Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22746
0
    return QualType();
22747
0
  }
22748
0
  return MapperType;
22749
0
}
22750
22751
Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
22752
    Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
22753
    SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
22754
0
    Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
22755
0
  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
22756
0
                      forRedeclarationInCurContext());
22757
  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22758
  //  A mapper-identifier may not be redeclared in the current scope for the
22759
  //  same type or for a type that is compatible according to the base language
22760
  //  rules.
22761
0
  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22762
0
  OMPDeclareMapperDecl *PrevDMD = nullptr;
22763
0
  bool InCompoundScope = true;
22764
0
  if (S != nullptr) {
22765
    // Find previous declaration with the same name not referenced in other
22766
    // declarations.
22767
0
    FunctionScopeInfo *ParentFn = getEnclosingFunction();
22768
0
    InCompoundScope =
22769
0
        (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22770
0
    LookupName(Lookup, S);
22771
0
    FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22772
0
                         /*AllowInlineNamespace=*/false);
22773
0
    llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22774
0
    LookupResult::Filter Filter = Lookup.makeFilter();
22775
0
    while (Filter.hasNext()) {
22776
0
      auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22777
0
      if (InCompoundScope) {
22778
0
        auto I = UsedAsPrevious.find(PrevDecl);
22779
0
        if (I == UsedAsPrevious.end())
22780
0
          UsedAsPrevious[PrevDecl] = false;
22781
0
        if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
22782
0
          UsedAsPrevious[D] = true;
22783
0
      }
22784
0
      PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22785
0
          PrevDecl->getLocation();
22786
0
    }
22787
0
    Filter.done();
22788
0
    if (InCompoundScope) {
22789
0
      for (const auto &PrevData : UsedAsPrevious) {
22790
0
        if (!PrevData.second) {
22791
0
          PrevDMD = PrevData.first;
22792
0
          break;
22793
0
        }
22794
0
      }
22795
0
    }
22796
0
  } else if (PrevDeclInScope) {
22797
0
    auto *PrevDMDInScope = PrevDMD =
22798
0
        cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22799
0
    do {
22800
0
      PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22801
0
          PrevDMDInScope->getLocation();
22802
0
      PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22803
0
    } while (PrevDMDInScope != nullptr);
22804
0
  }
22805
0
  const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
22806
0
  bool Invalid = false;
22807
0
  if (I != PreviousRedeclTypes.end()) {
22808
0
    Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22809
0
        << MapperType << Name;
22810
0
    Diag(I->second, diag::note_previous_definition);
22811
0
    Invalid = true;
22812
0
  }
22813
  // Build expressions for implicit maps of data members with 'default'
22814
  // mappers.
22815
0
  SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
22816
0
                                                  Clauses.end());
22817
0
  if (LangOpts.OpenMP >= 50)
22818
0
    processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
22819
0
  auto *DMD =
22820
0
      OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
22821
0
                                   ClausesWithImplicit, PrevDMD);
22822
0
  if (S)
22823
0
    PushOnScopeChains(DMD, S);
22824
0
  else
22825
0
    DC->addDecl(DMD);
22826
0
  DMD->setAccess(AS);
22827
0
  if (Invalid)
22828
0
    DMD->setInvalidDecl();
22829
22830
0
  auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22831
0
  VD->setDeclContext(DMD);
22832
0
  VD->setLexicalDeclContext(DMD);
22833
0
  DMD->addDecl(VD);
22834
0
  DMD->setMapperVarRef(MapperVarRef);
22835
22836
0
  return DeclGroupPtrTy::make(DeclGroupRef(DMD));
22837
0
}
22838
22839
ExprResult
22840
Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
22841
                                               SourceLocation StartLoc,
22842
0
                                               DeclarationName VN) {
22843
0
  TypeSourceInfo *TInfo =
22844
0
      Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
22845
0
  auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
22846
0
                             StartLoc, StartLoc, VN.getAsIdentifierInfo(),
22847
0
                             MapperType, TInfo, SC_None);
22848
0
  if (S)
22849
0
    PushOnScopeChains(VD, S, /*AddToContext=*/false);
22850
0
  Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
22851
0
  DSAStack->addDeclareMapperVarRef(E);
22852
0
  return E;
22853
0
}
22854
22855
0
void Sema::ActOnOpenMPIteratorVarDecl(VarDecl *VD) {
22856
0
  if (DSAStack->getDeclareMapperVarRef())
22857
0
    DSAStack->addIteratorVarDecl(VD);
22858
0
}
22859
22860
0
bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
22861
0
  assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22862
0
  const Expr *Ref = DSAStack->getDeclareMapperVarRef();
22863
0
  if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22864
0
    if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
22865
0
      return true;
22866
0
    if (VD->isUsableInConstantExpressions(Context))
22867
0
      return true;
22868
0
    if (LangOpts.OpenMP >= 52 && DSAStack->isIteratorVarDecl(VD))
22869
0
      return true;
22870
0
    return false;
22871
0
  }
22872
0
  return true;
22873
0
}
22874
22875
0
const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
22876
0
  assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22877
0
  return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
22878
0
}
22879
22880
OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
22881
                                           SourceLocation StartLoc,
22882
                                           SourceLocation LParenLoc,
22883
0
                                           SourceLocation EndLoc) {
22884
0
  Expr *ValExpr = NumTeams;
22885
0
  Stmt *HelperValStmt = nullptr;
22886
22887
  // OpenMP [teams Constrcut, Restrictions]
22888
  // The num_teams expression must evaluate to a positive integer value.
22889
0
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
22890
0
                                 /*StrictlyPositive=*/true))
22891
0
    return nullptr;
22892
22893
0
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22894
0
  OpenMPDirectiveKind CaptureRegion =
22895
0
      getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
22896
0
  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22897
0
    ValExpr = MakeFullExpr(ValExpr).get();
22898
0
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22899
0
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22900
0
    HelperValStmt = buildPreInits(Context, Captures);
22901
0
  }
22902
22903
0
  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
22904
0
                                         StartLoc, LParenLoc, EndLoc);
22905
0
}
22906
22907
OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
22908
                                              SourceLocation StartLoc,
22909
                                              SourceLocation LParenLoc,
22910
0
                                              SourceLocation EndLoc) {
22911
0
  Expr *ValExpr = ThreadLimit;
22912
0
  Stmt *HelperValStmt = nullptr;
22913
22914
  // OpenMP [teams Constrcut, Restrictions]
22915
  // The thread_limit expression must evaluate to a positive integer value.
22916
0
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
22917
0
                                 /*StrictlyPositive=*/true))
22918
0
    return nullptr;
22919
22920
0
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22921
0
  OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
22922
0
      DKind, OMPC_thread_limit, LangOpts.OpenMP);
22923
0
  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22924
0
    ValExpr = MakeFullExpr(ValExpr).get();
22925
0
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22926
0
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22927
0
    HelperValStmt = buildPreInits(Context, Captures);
22928
0
  }
22929
22930
0
  return new (Context) OMPThreadLimitClause(
22931
0
      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22932
0
}
22933
22934
OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
22935
                                           SourceLocation StartLoc,
22936
                                           SourceLocation LParenLoc,
22937
0
                                           SourceLocation EndLoc) {
22938
0
  Expr *ValExpr = Priority;
22939
0
  Stmt *HelperValStmt = nullptr;
22940
0
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22941
22942
  // OpenMP [2.9.1, task Constrcut]
22943
  // The priority-value is a non-negative numerical scalar expression.
22944
0
  if (!isNonNegativeIntegerValue(
22945
0
          ValExpr, *this, OMPC_priority,
22946
0
          /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22947
0
          DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22948
0
    return nullptr;
22949
22950
0
  return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
22951
0
                                         StartLoc, LParenLoc, EndLoc);
22952
0
}
22953
22954
OMPClause *Sema::ActOnOpenMPGrainsizeClause(
22955
    OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize,
22956
    SourceLocation StartLoc, SourceLocation LParenLoc,
22957
0
    SourceLocation ModifierLoc, SourceLocation EndLoc) {
22958
0
  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22959
0
         "Unexpected grainsize modifier in OpenMP < 51.");
22960
22961
0
  if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) {
22962
0
    std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0,
22963
0
                                                 OMPC_GRAINSIZE_unknown);
22964
0
    Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22965
0
        << Values << getOpenMPClauseName(OMPC_grainsize);
22966
0
    return nullptr;
22967
0
  }
22968
22969
0
  Expr *ValExpr = Grainsize;
22970
0
  Stmt *HelperValStmt = nullptr;
22971
0
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22972
22973
  // OpenMP [2.9.2, taskloop Constrcut]
22974
  // The parameter of the grainsize clause must be a positive integer
22975
  // expression.
22976
0
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
22977
0
                                 /*StrictlyPositive=*/true,
22978
0
                                 /*BuildCapture=*/true,
22979
0
                                 DSAStack->getCurrentDirective(),
22980
0
                                 &CaptureRegion, &HelperValStmt))
22981
0
    return nullptr;
22982
22983
0
  return new (Context)
22984
0
      OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22985
0
                         StartLoc, LParenLoc, ModifierLoc, EndLoc);
22986
0
}
22987
22988
OMPClause *Sema::ActOnOpenMPNumTasksClause(
22989
    OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks,
22990
    SourceLocation StartLoc, SourceLocation LParenLoc,
22991
0
    SourceLocation ModifierLoc, SourceLocation EndLoc) {
22992
0
  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22993
0
         "Unexpected num_tasks modifier in OpenMP < 51.");
22994
22995
0
  if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) {
22996
0
    std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0,
22997
0
                                                 OMPC_NUMTASKS_unknown);
22998
0
    Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22999
0
        << Values << getOpenMPClauseName(OMPC_num_tasks);
23000
0
    return nullptr;
23001
0
  }
23002
23003
0
  Expr *ValExpr = NumTasks;
23004
0
  Stmt *HelperValStmt = nullptr;
23005
0
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
23006
23007
  // OpenMP [2.9.2, taskloop Constrcut]
23008
  // The parameter of the num_tasks clause must be a positive integer
23009
  // expression.
23010
0
  if (!isNonNegativeIntegerValue(
23011
0
          ValExpr, *this, OMPC_num_tasks,
23012
0
          /*StrictlyPositive=*/true, /*BuildCapture=*/true,
23013
0
          DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
23014
0
    return nullptr;
23015
23016
0
  return new (Context)
23017
0
      OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
23018
0
                        StartLoc, LParenLoc, ModifierLoc, EndLoc);
23019
0
}
23020
23021
OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
23022
                                       SourceLocation LParenLoc,
23023
0
                                       SourceLocation EndLoc) {
23024
  // OpenMP [2.13.2, critical construct, Description]
23025
  // ... where hint-expression is an integer constant expression that evaluates
23026
  // to a valid lock hint.
23027
0
  ExprResult HintExpr =
23028
0
      VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
23029
0
  if (HintExpr.isInvalid())
23030
0
    return nullptr;
23031
0
  return new (Context)
23032
0
      OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
23033
0
}
23034
23035
/// Tries to find omp_event_handle_t type.
23036
static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
23037
0
                                DSAStackTy *Stack) {
23038
0
  QualType OMPEventHandleT = Stack->getOMPEventHandleT();
23039
0
  if (!OMPEventHandleT.isNull())
23040
0
    return true;
23041
0
  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
23042
0
  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
23043
0
  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
23044
0
    S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
23045
0
    return false;
23046
0
  }
23047
0
  Stack->setOMPEventHandleT(PT.get());
23048
0
  return true;
23049
0
}
23050
23051
OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
23052
                                         SourceLocation LParenLoc,
23053
0
                                         SourceLocation EndLoc) {
23054
0
  if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
23055
0
      !Evt->isInstantiationDependent() &&
23056
0
      !Evt->containsUnexpandedParameterPack()) {
23057
0
    if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
23058
0
      return nullptr;
23059
    // OpenMP 5.0, 2.10.1 task Construct.
23060
    // event-handle is a variable of the omp_event_handle_t type.
23061
0
    auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
23062
0
    if (!Ref) {
23063
0
      Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23064
0
          << "omp_event_handle_t" << 0 << Evt->getSourceRange();
23065
0
      return nullptr;
23066
0
    }
23067
0
    auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
23068
0
    if (!VD) {
23069
0
      Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23070
0
          << "omp_event_handle_t" << 0 << Evt->getSourceRange();
23071
0
      return nullptr;
23072
0
    }
23073
0
    if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
23074
0
                                        VD->getType()) ||
23075
0
        VD->getType().isConstant(Context)) {
23076
0
      Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23077
0
          << "omp_event_handle_t" << 1 << VD->getType()
23078
0
          << Evt->getSourceRange();
23079
0
      return nullptr;
23080
0
    }
23081
    // OpenMP 5.0, 2.10.1 task Construct
23082
    // [detach clause]... The event-handle will be considered as if it was
23083
    // specified on a firstprivate clause.
23084
0
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
23085
0
    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
23086
0
        DVar.RefExpr) {
23087
0
      Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
23088
0
          << getOpenMPClauseName(DVar.CKind)
23089
0
          << getOpenMPClauseName(OMPC_firstprivate);
23090
0
      reportOriginalDsa(*this, DSAStack, VD, DVar);
23091
0
      return nullptr;
23092
0
    }
23093
0
  }
23094
23095
0
  return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
23096
0
}
23097
23098
OMPClause *Sema::ActOnOpenMPDistScheduleClause(
23099
    OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
23100
    SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
23101
0
    SourceLocation EndLoc) {
23102
0
  if (Kind == OMPC_DIST_SCHEDULE_unknown) {
23103
0
    std::string Values;
23104
0
    Values += "'";
23105
0
    Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
23106
0
    Values += "'";
23107
0
    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23108
0
        << Values << getOpenMPClauseName(OMPC_dist_schedule);
23109
0
    return nullptr;
23110
0
  }
23111
0
  Expr *ValExpr = ChunkSize;
23112
0
  Stmt *HelperValStmt = nullptr;
23113
0
  if (ChunkSize) {
23114
0
    if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
23115
0
        !ChunkSize->isInstantiationDependent() &&
23116
0
        !ChunkSize->containsUnexpandedParameterPack()) {
23117
0
      SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
23118
0
      ExprResult Val =
23119
0
          PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
23120
0
      if (Val.isInvalid())
23121
0
        return nullptr;
23122
23123
0
      ValExpr = Val.get();
23124
23125
      // OpenMP [2.7.1, Restrictions]
23126
      //  chunk_size must be a loop invariant integer expression with a positive
23127
      //  value.
23128
0
      if (std::optional<llvm::APSInt> Result =
23129
0
              ValExpr->getIntegerConstantExpr(Context)) {
23130
0
        if (Result->isSigned() && !Result->isStrictlyPositive()) {
23131
0
          Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
23132
0
              << "dist_schedule" << ChunkSize->getSourceRange();
23133
0
          return nullptr;
23134
0
        }
23135
0
      } else if (getOpenMPCaptureRegionForClause(
23136
0
                     DSAStack->getCurrentDirective(), OMPC_dist_schedule,
23137
0
                     LangOpts.OpenMP) != OMPD_unknown &&
23138
0
                 !CurContext->isDependentContext()) {
23139
0
        ValExpr = MakeFullExpr(ValExpr).get();
23140
0
        llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23141
0
        ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
23142
0
        HelperValStmt = buildPreInits(Context, Captures);
23143
0
      }
23144
0
    }
23145
0
  }
23146
23147
0
  return new (Context)
23148
0
      OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
23149
0
                            Kind, ValExpr, HelperValStmt);
23150
0
}
23151
23152
OMPClause *Sema::ActOnOpenMPDefaultmapClause(
23153
    OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
23154
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
23155
0
    SourceLocation KindLoc, SourceLocation EndLoc) {
23156
0
  if (getLangOpts().OpenMP < 50) {
23157
0
    if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
23158
0
        Kind != OMPC_DEFAULTMAP_scalar) {
23159
0
      std::string Value;
23160
0
      SourceLocation Loc;
23161
0
      Value += "'";
23162
0
      if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
23163
0
        Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
23164
0
                                               OMPC_DEFAULTMAP_MODIFIER_tofrom);
23165
0
        Loc = MLoc;
23166
0
      } else {
23167
0
        Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
23168
0
                                               OMPC_DEFAULTMAP_scalar);
23169
0
        Loc = KindLoc;
23170
0
      }
23171
0
      Value += "'";
23172
0
      Diag(Loc, diag::err_omp_unexpected_clause_value)
23173
0
          << Value << getOpenMPClauseName(OMPC_defaultmap);
23174
0
      return nullptr;
23175
0
    }
23176
0
  } else {
23177
0
    bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
23178
0
    bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
23179
0
                            (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
23180
0
    if (!isDefaultmapKind || !isDefaultmapModifier) {
23181
0
      StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
23182
0
      if (LangOpts.OpenMP == 50) {
23183
0
        StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
23184
0
                                  "'firstprivate', 'none', 'default'";
23185
0
        if (!isDefaultmapKind && isDefaultmapModifier) {
23186
0
          Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23187
0
              << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23188
0
        } else if (isDefaultmapKind && !isDefaultmapModifier) {
23189
0
          Diag(MLoc, diag::err_omp_unexpected_clause_value)
23190
0
              << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23191
0
        } else {
23192
0
          Diag(MLoc, diag::err_omp_unexpected_clause_value)
23193
0
              << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23194
0
          Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23195
0
              << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23196
0
        }
23197
0
      } else {
23198
0
        StringRef ModifierValue =
23199
0
            "'alloc', 'from', 'to', 'tofrom', "
23200
0
            "'firstprivate', 'none', 'default', 'present'";
23201
0
        if (!isDefaultmapKind && isDefaultmapModifier) {
23202
0
          Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23203
0
              << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23204
0
        } else if (isDefaultmapKind && !isDefaultmapModifier) {
23205
0
          Diag(MLoc, diag::err_omp_unexpected_clause_value)
23206
0
              << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23207
0
        } else {
23208
0
          Diag(MLoc, diag::err_omp_unexpected_clause_value)
23209
0
              << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23210
0
          Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23211
0
              << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23212
0
        }
23213
0
      }
23214
0
      return nullptr;
23215
0
    }
23216
23217
    // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
23218
    //  At most one defaultmap clause for each category can appear on the
23219
    //  directive.
23220
0
    if (DSAStack->checkDefaultmapCategory(Kind)) {
23221
0
      Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
23222
0
      return nullptr;
23223
0
    }
23224
0
  }
23225
0
  if (Kind == OMPC_DEFAULTMAP_unknown) {
23226
    // Variable category is not specified - mark all categories.
23227
0
    DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
23228
0
    DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
23229
0
    DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
23230
0
  } else {
23231
0
    DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
23232
0
  }
23233
23234
0
  return new (Context)
23235
0
      OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
23236
0
}
23237
23238
bool Sema::ActOnStartOpenMPDeclareTargetContext(
23239
0
    DeclareTargetContextInfo &DTCI) {
23240
0
  DeclContext *CurLexicalContext = getCurLexicalContext();
23241
0
  if (!CurLexicalContext->isFileContext() &&
23242
0
      !CurLexicalContext->isExternCContext() &&
23243
0
      !CurLexicalContext->isExternCXXContext() &&
23244
0
      !isa<CXXRecordDecl>(CurLexicalContext) &&
23245
0
      !isa<ClassTemplateDecl>(CurLexicalContext) &&
23246
0
      !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
23247
0
      !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
23248
0
    Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
23249
0
    return false;
23250
0
  }
23251
23252
  // Report affected OpenMP target offloading behavior when in HIP lang-mode.
23253
0
  if (getLangOpts().HIP)
23254
0
    Diag(DTCI.Loc, diag::warn_hip_omp_target_directives);
23255
23256
0
  DeclareTargetNesting.push_back(DTCI);
23257
0
  return true;
23258
0
}
23259
23260
const Sema::DeclareTargetContextInfo
23261
0
Sema::ActOnOpenMPEndDeclareTargetDirective() {
23262
0
  assert(!DeclareTargetNesting.empty() &&
23263
0
         "check isInOpenMPDeclareTargetContext() first!");
23264
0
  return DeclareTargetNesting.pop_back_val();
23265
0
}
23266
23267
void Sema::ActOnFinishedOpenMPDeclareTargetContext(
23268
0
    DeclareTargetContextInfo &DTCI) {
23269
0
  for (auto &It : DTCI.ExplicitlyMapped)
23270
0
    ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
23271
0
}
23272
23273
46
void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() {
23274
46
  if (DeclareTargetNesting.empty())
23275
46
    return;
23276
0
  DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23277
0
  Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
23278
0
      << getOpenMPDirectiveName(DTCI.Kind);
23279
0
}
23280
23281
NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
23282
                                               CXXScopeSpec &ScopeSpec,
23283
0
                                               const DeclarationNameInfo &Id) {
23284
0
  LookupResult Lookup(*this, Id, LookupOrdinaryName);
23285
0
  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
23286
23287
0
  if (Lookup.isAmbiguous())
23288
0
    return nullptr;
23289
0
  Lookup.suppressDiagnostics();
23290
23291
0
  if (!Lookup.isSingleResult()) {
23292
0
    VarOrFuncDeclFilterCCC CCC(*this);
23293
0
    if (TypoCorrection Corrected =
23294
0
            CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
23295
0
                        CTK_ErrorRecovery)) {
23296
0
      diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
23297
0
                                  << Id.getName());
23298
0
      checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
23299
0
      return nullptr;
23300
0
    }
23301
23302
0
    Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
23303
0
    return nullptr;
23304
0
  }
23305
23306
0
  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
23307
0
  if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
23308
0
      !isa<FunctionTemplateDecl>(ND)) {
23309
0
    Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
23310
0
    return nullptr;
23311
0
  }
23312
0
  return ND;
23313
0
}
23314
23315
void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
23316
                                        OMPDeclareTargetDeclAttr::MapTypeTy MT,
23317
0
                                        DeclareTargetContextInfo &DTCI) {
23318
0
  assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
23319
0
          isa<FunctionTemplateDecl>(ND)) &&
23320
0
         "Expected variable, function or function template.");
23321
23322
  // Diagnose marking after use as it may lead to incorrect diagnosis and
23323
  // codegen.
23324
0
  if (LangOpts.OpenMP >= 50 &&
23325
0
      (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
23326
0
    Diag(Loc, diag::warn_omp_declare_target_after_first_use);
23327
23328
  // Report affected OpenMP target offloading behavior when in HIP lang-mode.
23329
0
  if (getLangOpts().HIP)
23330
0
    Diag(Loc, diag::warn_hip_omp_target_directives);
23331
23332
  // Explicit declare target lists have precedence.
23333
0
  const unsigned Level = -1;
23334
23335
0
  auto *VD = cast<ValueDecl>(ND);
23336
0
  std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23337
0
      OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23338
0
  if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT &&
23339
0
      (*ActiveAttr)->getLevel() == Level) {
23340
0
    Diag(Loc, diag::err_omp_device_type_mismatch)
23341
0
        << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
23342
0
        << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
23343
0
               (*ActiveAttr)->getDevType());
23344
0
    return;
23345
0
  }
23346
0
  if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
23347
0
      (*ActiveAttr)->getLevel() == Level) {
23348
0
    Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
23349
0
    return;
23350
0
  }
23351
23352
0
  if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
23353
0
    return;
23354
23355
0
  Expr *IndirectE = nullptr;
23356
0
  bool IsIndirect = false;
23357
0
  if (DTCI.Indirect) {
23358
0
    IndirectE = *DTCI.Indirect;
23359
0
    if (!IndirectE)
23360
0
      IsIndirect = true;
23361
0
  }
23362
0
  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23363
0
      Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
23364
0
      SourceRange(Loc, Loc));
23365
0
  ND->addAttr(A);
23366
0
  if (ASTMutationListener *ML = Context.getASTMutationListener())
23367
0
    ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
23368
0
  checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
23369
0
  if (auto *VD = dyn_cast<VarDecl>(ND);
23370
0
      LangOpts.OpenMP && VD && VD->hasAttr<OMPDeclareTargetDeclAttr>() &&
23371
0
      VD->hasGlobalStorage())
23372
0
    ActOnOpenMPDeclareTargetInitializer(ND);
23373
0
}
23374
23375
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
23376
0
                                     Sema &SemaRef, Decl *D) {
23377
0
  if (!D || !isa<VarDecl>(D))
23378
0
    return;
23379
0
  auto *VD = cast<VarDecl>(D);
23380
0
  std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
23381
0
      OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
23382
0
  if (SemaRef.LangOpts.OpenMP >= 50 &&
23383
0
      (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
23384
0
       SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
23385
0
      VD->hasGlobalStorage()) {
23386
0
    if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To &&
23387
0
                   *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
23388
      // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
23389
      // If a lambda declaration and definition appears between a
23390
      // declare target directive and the matching end declare target
23391
      // directive, all variables that are captured by the lambda
23392
      // expression must also appear in a to clause.
23393
0
      SemaRef.Diag(VD->getLocation(),
23394
0
                   diag::err_omp_lambda_capture_in_declare_target_not_to);
23395
0
      SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
23396
0
          << VD << 0 << SR;
23397
0
      return;
23398
0
    }
23399
0
  }
23400
0
  if (MapTy)
23401
0
    return;
23402
0
  SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
23403
0
  SemaRef.Diag(SL, diag::note_used_here) << SR;
23404
0
}
23405
23406
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
23407
                                   Sema &SemaRef, DSAStackTy *Stack,
23408
0
                                   ValueDecl *VD) {
23409
0
  return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
23410
0
         checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
23411
0
                           /*FullCheck=*/false);
23412
0
}
23413
23414
void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
23415
0
                                            SourceLocation IdLoc) {
23416
0
  if (!D || D->isInvalidDecl())
23417
0
    return;
23418
0
  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
23419
0
  SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
23420
0
  if (auto *VD = dyn_cast<VarDecl>(D)) {
23421
    // Only global variables can be marked as declare target.
23422
0
    if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23423
0
        !VD->isStaticDataMember())
23424
0
      return;
23425
    // 2.10.6: threadprivate variable cannot appear in a declare target
23426
    // directive.
23427
0
    if (DSAStack->isThreadPrivate(VD)) {
23428
0
      Diag(SL, diag::err_omp_threadprivate_in_target);
23429
0
      reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
23430
0
      return;
23431
0
    }
23432
0
  }
23433
0
  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
23434
0
    D = FTD->getTemplatedDecl();
23435
0
  if (auto *FD = dyn_cast<FunctionDecl>(D)) {
23436
0
    std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
23437
0
        OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
23438
0
    if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
23439
0
      Diag(IdLoc, diag::err_omp_function_in_link_clause);
23440
0
      Diag(FD->getLocation(), diag::note_defined_here) << FD;
23441
0
      return;
23442
0
    }
23443
0
  }
23444
0
  if (auto *VD = dyn_cast<ValueDecl>(D)) {
23445
    // Problem if any with var declared with incomplete type will be reported
23446
    // as normal, so no need to check it here.
23447
0
    if ((E || !VD->getType()->isIncompleteType()) &&
23448
0
        !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
23449
0
      return;
23450
0
    if (!E && isInOpenMPDeclareTargetContext()) {
23451
      // Checking declaration inside declare target region.
23452
0
      if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
23453
0
          isa<FunctionTemplateDecl>(D)) {
23454
0
        std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23455
0
            OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23456
0
        unsigned Level = DeclareTargetNesting.size();
23457
0
        if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
23458
0
          return;
23459
0
        DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23460
0
        Expr *IndirectE = nullptr;
23461
0
        bool IsIndirect = false;
23462
0
        if (DTCI.Indirect) {
23463
0
          IndirectE = *DTCI.Indirect;
23464
0
          if (!IndirectE)
23465
0
            IsIndirect = true;
23466
0
        }
23467
0
        auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23468
0
            Context,
23469
0
            getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
23470
0
                                       : OMPDeclareTargetDeclAttr::MT_To,
23471
0
            DTCI.DT, IndirectE, IsIndirect, Level,
23472
0
            SourceRange(DTCI.Loc, DTCI.Loc));
23473
0
        D->addAttr(A);
23474
0
        if (ASTMutationListener *ML = Context.getASTMutationListener())
23475
0
          ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
23476
0
      }
23477
0
      return;
23478
0
    }
23479
0
  }
23480
0
  if (!E)
23481
0
    return;
23482
0
  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
23483
0
}
23484
23485
/// This class visits every VarDecl that the initializer references and adds
23486
/// OMPDeclareTargetDeclAttr to each of them.
23487
class GlobalDeclRefChecker final
23488
    : public StmtVisitor<GlobalDeclRefChecker> {
23489
  SmallVector<VarDecl *> DeclVector;
23490
  Attr *A;
23491
23492
public:
23493
  /// A StmtVisitor class function that visits all DeclRefExpr and adds
23494
  /// OMPDeclareTargetDeclAttr to them.
23495
0
  void VisitDeclRefExpr(DeclRefExpr *Node) {
23496
0
    if (auto *VD = dyn_cast<VarDecl>(Node->getDecl())) {
23497
0
      VD->addAttr(A);
23498
0
      DeclVector.push_back(VD);
23499
0
    }
23500
0
  }
23501
  /// A function that iterates across each of the Expr's children.
23502
0
  void VisitExpr(Expr *Ex) {
23503
0
    for (auto *Child : Ex->children()) {
23504
0
      Visit(Child);
23505
0
    }
23506
0
  }
23507
  /// A function that keeps a record of all the Decls that are variables, has
23508
  /// OMPDeclareTargetDeclAttr, and has global storage in the DeclVector. Pop
23509
  /// each Decl one at a time and use the inherited 'visit' functions to look
23510
  /// for DeclRefExpr.
23511
0
  void declareTargetInitializer(Decl *TD) {
23512
0
    A = TD->getAttr<OMPDeclareTargetDeclAttr>();
23513
0
    DeclVector.push_back(cast<VarDecl>(TD));
23514
0
    while (!DeclVector.empty()) {
23515
0
      VarDecl *TargetVarDecl = DeclVector.pop_back_val();
23516
0
      if (TargetVarDecl->hasAttr<OMPDeclareTargetDeclAttr>() &&
23517
0
          TargetVarDecl->hasInit() && TargetVarDecl->hasGlobalStorage()) {
23518
0
        if (Expr *Ex = TargetVarDecl->getInit())
23519
0
          Visit(Ex);
23520
0
      }
23521
0
    }
23522
0
  }
23523
};
23524
23525
/// Adding OMPDeclareTargetDeclAttr to variables with static storage
23526
/// duration that are referenced in the initializer expression list of
23527
/// variables with static storage duration in declare target directive.
23528
0
void Sema::ActOnOpenMPDeclareTargetInitializer(Decl *TargetDecl) {
23529
0
  GlobalDeclRefChecker Checker;
23530
0
  if (isa<VarDecl>(TargetDecl))
23531
0
    Checker.declareTargetInitializer(TargetDecl);
23532
0
}
23533
23534
OMPClause *Sema::ActOnOpenMPToClause(
23535
    ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23536
    ArrayRef<SourceLocation> MotionModifiersLoc,
23537
    CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23538
    SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23539
0
    const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23540
0
  OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23541
0
                                          OMPC_MOTION_MODIFIER_unknown};
23542
0
  SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23543
23544
  // Process motion-modifiers, flag errors for duplicate modifiers.
23545
0
  unsigned Count = 0;
23546
0
  for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23547
0
    if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23548
0
        llvm::is_contained(Modifiers, MotionModifiers[I])) {
23549
0
      Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23550
0
      continue;
23551
0
    }
23552
0
    assert(Count < NumberOfOMPMotionModifiers &&
23553
0
           "Modifiers exceed the allowed number of motion modifiers");
23554
0
    Modifiers[Count] = MotionModifiers[I];
23555
0
    ModifiersLoc[Count] = MotionModifiersLoc[I];
23556
0
    ++Count;
23557
0
  }
23558
23559
0
  MappableVarListInfo MVLI(VarList);
23560
0
  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
23561
0
                              MapperIdScopeSpec, MapperId, UnresolvedMappers);
23562
0
  if (MVLI.ProcessedVarList.empty())
23563
0
    return nullptr;
23564
23565
0
  return OMPToClause::Create(
23566
0
      Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23567
0
      MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23568
0
      MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23569
0
}
23570
23571
OMPClause *Sema::ActOnOpenMPFromClause(
23572
    ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23573
    ArrayRef<SourceLocation> MotionModifiersLoc,
23574
    CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23575
    SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23576
0
    const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23577
0
  OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23578
0
                                          OMPC_MOTION_MODIFIER_unknown};
23579
0
  SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23580
23581
  // Process motion-modifiers, flag errors for duplicate modifiers.
23582
0
  unsigned Count = 0;
23583
0
  for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23584
0
    if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23585
0
        llvm::is_contained(Modifiers, MotionModifiers[I])) {
23586
0
      Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23587
0
      continue;
23588
0
    }
23589
0
    assert(Count < NumberOfOMPMotionModifiers &&
23590
0
           "Modifiers exceed the allowed number of motion modifiers");
23591
0
    Modifiers[Count] = MotionModifiers[I];
23592
0
    ModifiersLoc[Count] = MotionModifiersLoc[I];
23593
0
    ++Count;
23594
0
  }
23595
23596
0
  MappableVarListInfo MVLI(VarList);
23597
0
  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
23598
0
                              MapperIdScopeSpec, MapperId, UnresolvedMappers);
23599
0
  if (MVLI.ProcessedVarList.empty())
23600
0
    return nullptr;
23601
23602
0
  return OMPFromClause::Create(
23603
0
      Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23604
0
      MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23605
0
      MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23606
0
}
23607
23608
OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
23609
0
                                               const OMPVarListLocTy &Locs) {
23610
0
  MappableVarListInfo MVLI(VarList);
23611
0
  SmallVector<Expr *, 8> PrivateCopies;
23612
0
  SmallVector<Expr *, 8> Inits;
23613
23614
0
  for (Expr *RefExpr : VarList) {
23615
0
    assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
23616
0
    SourceLocation ELoc;
23617
0
    SourceRange ERange;
23618
0
    Expr *SimpleRefExpr = RefExpr;
23619
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23620
0
    if (Res.second) {
23621
      // It will be analyzed later.
23622
0
      MVLI.ProcessedVarList.push_back(RefExpr);
23623
0
      PrivateCopies.push_back(nullptr);
23624
0
      Inits.push_back(nullptr);
23625
0
    }
23626
0
    ValueDecl *D = Res.first;
23627
0
    if (!D)
23628
0
      continue;
23629
23630
0
    QualType Type = D->getType();
23631
0
    Type = Type.getNonReferenceType().getUnqualifiedType();
23632
23633
0
    auto *VD = dyn_cast<VarDecl>(D);
23634
23635
    // Item should be a pointer or reference to pointer.
23636
0
    if (!Type->isPointerType()) {
23637
0
      Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23638
0
          << 0 << RefExpr->getSourceRange();
23639
0
      continue;
23640
0
    }
23641
23642
    // Build the private variable and the expression that refers to it.
23643
0
    auto VDPrivate =
23644
0
        buildVarDecl(*this, ELoc, Type, D->getName(),
23645
0
                     D->hasAttrs() ? &D->getAttrs() : nullptr,
23646
0
                     VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
23647
0
    if (VDPrivate->isInvalidDecl())
23648
0
      continue;
23649
23650
0
    CurContext->addDecl(VDPrivate);
23651
0
    DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
23652
0
        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23653
23654
    // Add temporary variable to initialize the private copy of the pointer.
23655
0
    VarDecl *VDInit =
23656
0
        buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
23657
0
    DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
23658
0
        *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
23659
0
    AddInitializerToDecl(VDPrivate,
23660
0
                         DefaultLvalueConversion(VDInitRefExpr).get(),
23661
0
                         /*DirectInit=*/false);
23662
23663
    // If required, build a capture to implement the privatization initialized
23664
    // with the current list item value.
23665
0
    DeclRefExpr *Ref = nullptr;
23666
0
    if (!VD)
23667
0
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23668
0
    MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23669
0
    PrivateCopies.push_back(VDPrivateRefExpr);
23670
0
    Inits.push_back(VDInitRefExpr);
23671
23672
    // We need to add a data sharing attribute for this variable to make sure it
23673
    // is correctly captured. A variable that shows up in a use_device_ptr has
23674
    // similar properties of a first private variable.
23675
0
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23676
23677
    // Create a mappable component for the list item. List items in this clause
23678
    // only need a component.
23679
0
    MVLI.VarBaseDeclarations.push_back(D);
23680
0
    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23681
0
    MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
23682
0
                                           /*IsNonContiguous=*/false);
23683
0
  }
23684
23685
0
  if (MVLI.ProcessedVarList.empty())
23686
0
    return nullptr;
23687
23688
0
  return OMPUseDevicePtrClause::Create(
23689
0
      Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
23690
0
      MVLI.VarBaseDeclarations, MVLI.VarComponents);
23691
0
}
23692
23693
OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
23694
0
                                                const OMPVarListLocTy &Locs) {
23695
0
  MappableVarListInfo MVLI(VarList);
23696
23697
0
  for (Expr *RefExpr : VarList) {
23698
0
    assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
23699
0
    SourceLocation ELoc;
23700
0
    SourceRange ERange;
23701
0
    Expr *SimpleRefExpr = RefExpr;
23702
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23703
0
                              /*AllowArraySection=*/true);
23704
0
    if (Res.second) {
23705
      // It will be analyzed later.
23706
0
      MVLI.ProcessedVarList.push_back(RefExpr);
23707
0
    }
23708
0
    ValueDecl *D = Res.first;
23709
0
    if (!D)
23710
0
      continue;
23711
0
    auto *VD = dyn_cast<VarDecl>(D);
23712
23713
    // If required, build a capture to implement the privatization initialized
23714
    // with the current list item value.
23715
0
    DeclRefExpr *Ref = nullptr;
23716
0
    if (!VD)
23717
0
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23718
0
    MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23719
23720
    // We need to add a data sharing attribute for this variable to make sure it
23721
    // is correctly captured. A variable that shows up in a use_device_addr has
23722
    // similar properties of a first private variable.
23723
0
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23724
23725
    // Create a mappable component for the list item. List items in this clause
23726
    // only need a component.
23727
0
    MVLI.VarBaseDeclarations.push_back(D);
23728
0
    MVLI.VarComponents.emplace_back();
23729
0
    Expr *Component = SimpleRefExpr;
23730
0
    if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23731
0
               isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23732
0
      Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23733
0
    MVLI.VarComponents.back().emplace_back(Component, D,
23734
0
                                           /*IsNonContiguous=*/false);
23735
0
  }
23736
23737
0
  if (MVLI.ProcessedVarList.empty())
23738
0
    return nullptr;
23739
23740
0
  return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23741
0
                                        MVLI.VarBaseDeclarations,
23742
0
                                        MVLI.VarComponents);
23743
0
}
23744
23745
OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
23746
0
                                              const OMPVarListLocTy &Locs) {
23747
0
  MappableVarListInfo MVLI(VarList);
23748
0
  for (Expr *RefExpr : VarList) {
23749
0
    assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
23750
0
    SourceLocation ELoc;
23751
0
    SourceRange ERange;
23752
0
    Expr *SimpleRefExpr = RefExpr;
23753
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23754
0
    if (Res.second) {
23755
      // It will be analyzed later.
23756
0
      MVLI.ProcessedVarList.push_back(RefExpr);
23757
0
    }
23758
0
    ValueDecl *D = Res.first;
23759
0
    if (!D)
23760
0
      continue;
23761
23762
0
    QualType Type = D->getType();
23763
    // item should be a pointer or array or reference to pointer or array
23764
0
    if (!Type.getNonReferenceType()->isPointerType() &&
23765
0
        !Type.getNonReferenceType()->isArrayType()) {
23766
0
      Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23767
0
          << 0 << RefExpr->getSourceRange();
23768
0
      continue;
23769
0
    }
23770
23771
    // Check if the declaration in the clause does not show up in any data
23772
    // sharing attribute.
23773
0
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23774
0
    if (isOpenMPPrivate(DVar.CKind)) {
23775
0
      Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23776
0
          << getOpenMPClauseName(DVar.CKind)
23777
0
          << getOpenMPClauseName(OMPC_is_device_ptr)
23778
0
          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23779
0
      reportOriginalDsa(*this, DSAStack, D, DVar);
23780
0
      continue;
23781
0
    }
23782
23783
0
    const Expr *ConflictExpr;
23784
0
    if (DSAStack->checkMappableExprComponentListsForDecl(
23785
0
            D, /*CurrentRegionOnly=*/true,
23786
0
            [&ConflictExpr](
23787
0
                OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23788
0
                OpenMPClauseKind) -> bool {
23789
0
              ConflictExpr = R.front().getAssociatedExpression();
23790
0
              return true;
23791
0
            })) {
23792
0
      Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23793
0
      Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23794
0
          << ConflictExpr->getSourceRange();
23795
0
      continue;
23796
0
    }
23797
23798
    // Store the components in the stack so that they can be used to check
23799
    // against other clauses later on.
23800
0
    OMPClauseMappableExprCommon::MappableComponent MC(
23801
0
        SimpleRefExpr, D, /*IsNonContiguous=*/false);
23802
0
    DSAStack->addMappableExpressionComponents(
23803
0
        D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
23804
23805
    // Record the expression we've just processed.
23806
0
    MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23807
23808
    // Create a mappable component for the list item. List items in this clause
23809
    // only need a component. We use a null declaration to signal fields in
23810
    // 'this'.
23811
0
    assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23812
0
            isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23813
0
           "Unexpected device pointer expression!");
23814
0
    MVLI.VarBaseDeclarations.push_back(
23815
0
        isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23816
0
    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23817
0
    MVLI.VarComponents.back().push_back(MC);
23818
0
  }
23819
23820
0
  if (MVLI.ProcessedVarList.empty())
23821
0
    return nullptr;
23822
23823
0
  return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23824
0
                                      MVLI.VarBaseDeclarations,
23825
0
                                      MVLI.VarComponents);
23826
0
}
23827
23828
OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
23829
0
                                                const OMPVarListLocTy &Locs) {
23830
0
  MappableVarListInfo MVLI(VarList);
23831
0
  for (Expr *RefExpr : VarList) {
23832
0
    assert(RefExpr && "NULL expr in OpenMP has_device_addr clause.");
23833
0
    SourceLocation ELoc;
23834
0
    SourceRange ERange;
23835
0
    Expr *SimpleRefExpr = RefExpr;
23836
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23837
0
                              /*AllowArraySection=*/true);
23838
0
    if (Res.second) {
23839
      // It will be analyzed later.
23840
0
      MVLI.ProcessedVarList.push_back(RefExpr);
23841
0
    }
23842
0
    ValueDecl *D = Res.first;
23843
0
    if (!D)
23844
0
      continue;
23845
23846
    // Check if the declaration in the clause does not show up in any data
23847
    // sharing attribute.
23848
0
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23849
0
    if (isOpenMPPrivate(DVar.CKind)) {
23850
0
      Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23851
0
          << getOpenMPClauseName(DVar.CKind)
23852
0
          << getOpenMPClauseName(OMPC_has_device_addr)
23853
0
          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23854
0
      reportOriginalDsa(*this, DSAStack, D, DVar);
23855
0
      continue;
23856
0
    }
23857
23858
0
    const Expr *ConflictExpr;
23859
0
    if (DSAStack->checkMappableExprComponentListsForDecl(
23860
0
            D, /*CurrentRegionOnly=*/true,
23861
0
            [&ConflictExpr](
23862
0
                OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23863
0
                OpenMPClauseKind) -> bool {
23864
0
              ConflictExpr = R.front().getAssociatedExpression();
23865
0
              return true;
23866
0
            })) {
23867
0
      Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23868
0
      Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23869
0
          << ConflictExpr->getSourceRange();
23870
0
      continue;
23871
0
    }
23872
23873
    // Store the components in the stack so that they can be used to check
23874
    // against other clauses later on.
23875
0
    Expr *Component = SimpleRefExpr;
23876
0
    auto *VD = dyn_cast<VarDecl>(D);
23877
0
    if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23878
0
               isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23879
0
      Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23880
0
    OMPClauseMappableExprCommon::MappableComponent MC(
23881
0
        Component, D, /*IsNonContiguous=*/false);
23882
0
    DSAStack->addMappableExpressionComponents(
23883
0
        D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
23884
23885
    // Record the expression we've just processed.
23886
0
    if (!VD && !CurContext->isDependentContext()) {
23887
0
      DeclRefExpr *Ref =
23888
0
          buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23889
0
      assert(Ref && "has_device_addr capture failed");
23890
0
      MVLI.ProcessedVarList.push_back(Ref);
23891
0
    } else
23892
0
      MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23893
23894
    // Create a mappable component for the list item. List items in this clause
23895
    // only need a component. We use a null declaration to signal fields in
23896
    // 'this'.
23897
0
    assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23898
0
            isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23899
0
           "Unexpected device pointer expression!");
23900
0
    MVLI.VarBaseDeclarations.push_back(
23901
0
        isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23902
0
    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23903
0
    MVLI.VarComponents.back().push_back(MC);
23904
0
  }
23905
23906
0
  if (MVLI.ProcessedVarList.empty())
23907
0
    return nullptr;
23908
23909
0
  return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23910
0
                                        MVLI.VarBaseDeclarations,
23911
0
                                        MVLI.VarComponents);
23912
0
}
23913
23914
OMPClause *Sema::ActOnOpenMPAllocateClause(
23915
    Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23916
0
    SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
23917
0
  if (Allocator) {
23918
    // OpenMP [2.11.4 allocate Clause, Description]
23919
    // allocator is an expression of omp_allocator_handle_t type.
23920
0
    if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
23921
0
      return nullptr;
23922
23923
0
    ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
23924
0
    if (AllocatorRes.isInvalid())
23925
0
      return nullptr;
23926
0
    AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
23927
0
                                             DSAStack->getOMPAllocatorHandleT(),
23928
0
                                             Sema::AA_Initializing,
23929
0
                                             /*AllowExplicit=*/true);
23930
0
    if (AllocatorRes.isInvalid())
23931
0
      return nullptr;
23932
0
    Allocator = AllocatorRes.get();
23933
0
  } else {
23934
    // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23935
    // allocate clauses that appear on a target construct or on constructs in a
23936
    // target region must specify an allocator expression unless a requires
23937
    // directive with the dynamic_allocators clause is present in the same
23938
    // compilation unit.
23939
0
    if (LangOpts.OpenMPIsTargetDevice &&
23940
0
        !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
23941
0
      targetDiag(StartLoc, diag::err_expected_allocator_expression);
23942
0
  }
23943
  // Analyze and build list of variables.
23944
0
  SmallVector<Expr *, 8> Vars;
23945
0
  for (Expr *RefExpr : VarList) {
23946
0
    assert(RefExpr && "NULL expr in OpenMP private clause.");
23947
0
    SourceLocation ELoc;
23948
0
    SourceRange ERange;
23949
0
    Expr *SimpleRefExpr = RefExpr;
23950
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23951
0
    if (Res.second) {
23952
      // It will be analyzed later.
23953
0
      Vars.push_back(RefExpr);
23954
0
    }
23955
0
    ValueDecl *D = Res.first;
23956
0
    if (!D)
23957
0
      continue;
23958
23959
0
    auto *VD = dyn_cast<VarDecl>(D);
23960
0
    DeclRefExpr *Ref = nullptr;
23961
0
    if (!VD && !CurContext->isDependentContext())
23962
0
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
23963
0
    Vars.push_back((VD || CurContext->isDependentContext())
23964
0
                       ? RefExpr->IgnoreParens()
23965
0
                       : Ref);
23966
0
  }
23967
23968
0
  if (Vars.empty())
23969
0
    return nullptr;
23970
23971
0
  if (Allocator)
23972
0
    DSAStack->addInnerAllocatorExpr(Allocator);
23973
0
  return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
23974
0
                                   ColonLoc, EndLoc, Vars);
23975
0
}
23976
23977
OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
23978
                                              SourceLocation StartLoc,
23979
                                              SourceLocation LParenLoc,
23980
0
                                              SourceLocation EndLoc) {
23981
0
  SmallVector<Expr *, 8> Vars;
23982
0
  for (Expr *RefExpr : VarList) {
23983
0
    assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23984
0
    SourceLocation ELoc;
23985
0
    SourceRange ERange;
23986
0
    Expr *SimpleRefExpr = RefExpr;
23987
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23988
0
    if (Res.second)
23989
      // It will be analyzed later.
23990
0
      Vars.push_back(RefExpr);
23991
0
    ValueDecl *D = Res.first;
23992
0
    if (!D)
23993
0
      continue;
23994
23995
    // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23996
    // A list-item cannot appear in more than one nontemporal clause.
23997
0
    if (const Expr *PrevRef =
23998
0
            DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
23999
0
      Diag(ELoc, diag::err_omp_used_in_clause_twice)
24000
0
          << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
24001
0
      Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
24002
0
          << getOpenMPClauseName(OMPC_nontemporal);
24003
0
      continue;
24004
0
    }
24005
24006
0
    Vars.push_back(RefExpr);
24007
0
  }
24008
24009
0
  if (Vars.empty())
24010
0
    return nullptr;
24011
24012
0
  return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24013
0
                                      Vars);
24014
0
}
24015
24016
StmtResult Sema::ActOnOpenMPScopeDirective(ArrayRef<OMPClause *> Clauses,
24017
                                           Stmt *AStmt, SourceLocation StartLoc,
24018
0
                                           SourceLocation EndLoc) {
24019
0
  if (!AStmt)
24020
0
    return StmtError();
24021
24022
0
  setFunctionHasBranchProtectedScope();
24023
24024
0
  return OMPScopeDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
24025
0
}
24026
24027
OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
24028
                                            SourceLocation StartLoc,
24029
                                            SourceLocation LParenLoc,
24030
0
                                            SourceLocation EndLoc) {
24031
0
  SmallVector<Expr *, 8> Vars;
24032
0
  for (Expr *RefExpr : VarList) {
24033
0
    assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
24034
0
    SourceLocation ELoc;
24035
0
    SourceRange ERange;
24036
0
    Expr *SimpleRefExpr = RefExpr;
24037
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
24038
0
                              /*AllowArraySection=*/true);
24039
0
    if (Res.second)
24040
      // It will be analyzed later.
24041
0
      Vars.push_back(RefExpr);
24042
0
    ValueDecl *D = Res.first;
24043
0
    if (!D)
24044
0
      continue;
24045
24046
0
    const DSAStackTy::DSAVarData DVar =
24047
0
        DSAStack->getTopDSA(D, /*FromParent=*/true);
24048
    // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
24049
    // A list item that appears in the inclusive or exclusive clause must appear
24050
    // in a reduction clause with the inscan modifier on the enclosing
24051
    // worksharing-loop, worksharing-loop SIMD, or simd construct.
24052
0
    if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
24053
0
      Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24054
0
          << RefExpr->getSourceRange();
24055
24056
0
    if (DSAStack->getParentDirective() != OMPD_unknown)
24057
0
      DSAStack->markDeclAsUsedInScanDirective(D);
24058
0
    Vars.push_back(RefExpr);
24059
0
  }
24060
24061
0
  if (Vars.empty())
24062
0
    return nullptr;
24063
24064
0
  return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
24065
0
}
24066
24067
OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
24068
                                            SourceLocation StartLoc,
24069
                                            SourceLocation LParenLoc,
24070
0
                                            SourceLocation EndLoc) {
24071
0
  SmallVector<Expr *, 8> Vars;
24072
0
  for (Expr *RefExpr : VarList) {
24073
0
    assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
24074
0
    SourceLocation ELoc;
24075
0
    SourceRange ERange;
24076
0
    Expr *SimpleRefExpr = RefExpr;
24077
0
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
24078
0
                              /*AllowArraySection=*/true);
24079
0
    if (Res.second)
24080
      // It will be analyzed later.
24081
0
      Vars.push_back(RefExpr);
24082
0
    ValueDecl *D = Res.first;
24083
0
    if (!D)
24084
0
      continue;
24085
24086
0
    OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
24087
0
    DSAStackTy::DSAVarData DVar;
24088
0
    if (ParentDirective != OMPD_unknown)
24089
0
      DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
24090
    // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
24091
    // A list item that appears in the inclusive or exclusive clause must appear
24092
    // in a reduction clause with the inscan modifier on the enclosing
24093
    // worksharing-loop, worksharing-loop SIMD, or simd construct.
24094
0
    if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
24095
0
        DVar.Modifier != OMPC_REDUCTION_inscan) {
24096
0
      Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24097
0
          << RefExpr->getSourceRange();
24098
0
    } else {
24099
0
      DSAStack->markDeclAsUsedInScanDirective(D);
24100
0
    }
24101
0
    Vars.push_back(RefExpr);
24102
0
  }
24103
24104
0
  if (Vars.empty())
24105
0
    return nullptr;
24106
24107
0
  return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
24108
0
}
24109
24110
/// Tries to find omp_alloctrait_t type.
24111
0
static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
24112
0
  QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
24113
0
  if (!OMPAlloctraitT.isNull())
24114
0
    return true;
24115
0
  IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
24116
0
  ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
24117
0
  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
24118
0
    S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
24119
0
    return false;
24120
0
  }
24121
0
  Stack->setOMPAlloctraitT(PT.get());
24122
0
  return true;
24123
0
}
24124
24125
OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
24126
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
24127
0
    ArrayRef<UsesAllocatorsData> Data) {
24128
  // OpenMP [2.12.5, target Construct]
24129
  // allocator is an identifier of omp_allocator_handle_t type.
24130
0
  if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
24131
0
    return nullptr;
24132
  // OpenMP [2.12.5, target Construct]
24133
  // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
24134
0
  if (llvm::any_of(
24135
0
          Data,
24136
0
          [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
24137
0
      !findOMPAlloctraitT(*this, StartLoc, DSAStack))
24138
0
    return nullptr;
24139
0
  llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
24140
0
  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
24141
0
    auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
24142
0
    StringRef Allocator =
24143
0
        OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
24144
0
    DeclarationName AllocatorName = &Context.Idents.get(Allocator);
24145
0
    PredefinedAllocators.insert(LookupSingleName(
24146
0
        TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
24147
0
  }
24148
24149
0
  SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
24150
0
  for (const UsesAllocatorsData &D : Data) {
24151
0
    Expr *AllocatorExpr = nullptr;
24152
    // Check allocator expression.
24153
0
    if (D.Allocator->isTypeDependent()) {
24154
0
      AllocatorExpr = D.Allocator;
24155
0
    } else {
24156
      // Traits were specified - need to assign new allocator to the specified
24157
      // allocator, so it must be an lvalue.
24158
0
      AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
24159
0
      auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
24160
0
      bool IsPredefinedAllocator = false;
24161
0
      if (DRE) {
24162
0
        OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
24163
0
            getAllocatorKind(*this, DSAStack, AllocatorExpr);
24164
0
        IsPredefinedAllocator =
24165
0
            AllocatorTy !=
24166
0
            OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
24167
0
      }
24168
0
      QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT();
24169
0
      QualType AllocatorExprType = AllocatorExpr->getType();
24170
0
      bool IsTypeCompatible = IsPredefinedAllocator;
24171
0
      IsTypeCompatible = IsTypeCompatible ||
24172
0
                         Context.hasSameUnqualifiedType(AllocatorExprType,
24173
0
                                                        OMPAllocatorHandleT);
24174
0
      IsTypeCompatible =
24175
0
          IsTypeCompatible ||
24176
0
          Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT);
24177
0
      bool IsNonConstantLValue =
24178
0
          !AllocatorExprType.isConstant(Context) && AllocatorExpr->isLValue();
24179
0
      if (!DRE || !IsTypeCompatible ||
24180
0
          (!IsPredefinedAllocator && !IsNonConstantLValue)) {
24181
0
        Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
24182
0
            << "omp_allocator_handle_t" << (DRE ? 1 : 0)
24183
0
            << AllocatorExpr->getType() << D.Allocator->getSourceRange();
24184
0
        continue;
24185
0
      }
24186
      // OpenMP [2.12.5, target Construct]
24187
      // Predefined allocators appearing in a uses_allocators clause cannot have
24188
      // traits specified.
24189
0
      if (IsPredefinedAllocator && D.AllocatorTraits) {
24190
0
        Diag(D.AllocatorTraits->getExprLoc(),
24191
0
             diag::err_omp_predefined_allocator_with_traits)
24192
0
            << D.AllocatorTraits->getSourceRange();
24193
0
        Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
24194
0
            << cast<NamedDecl>(DRE->getDecl())->getName()
24195
0
            << D.Allocator->getSourceRange();
24196
0
        continue;
24197
0
      }
24198
      // OpenMP [2.12.5, target Construct]
24199
      // Non-predefined allocators appearing in a uses_allocators clause must
24200
      // have traits specified.
24201
0
      if (!IsPredefinedAllocator && !D.AllocatorTraits) {
24202
0
        Diag(D.Allocator->getExprLoc(),
24203
0
             diag::err_omp_nonpredefined_allocator_without_traits);
24204
0
        continue;
24205
0
      }
24206
      // No allocator traits - just convert it to rvalue.
24207
0
      if (!D.AllocatorTraits)
24208
0
        AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
24209
0
      DSAStack->addUsesAllocatorsDecl(
24210
0
          DRE->getDecl(),
24211
0
          IsPredefinedAllocator
24212
0
              ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
24213
0
              : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
24214
0
    }
24215
0
    Expr *AllocatorTraitsExpr = nullptr;
24216
0
    if (D.AllocatorTraits) {
24217
0
      if (D.AllocatorTraits->isTypeDependent()) {
24218
0
        AllocatorTraitsExpr = D.AllocatorTraits;
24219
0
      } else {
24220
        // OpenMP [2.12.5, target Construct]
24221
        // Arrays that contain allocator traits that appear in a uses_allocators
24222
        // clause must be constant arrays, have constant values and be defined
24223
        // in the same scope as the construct in which the clause appears.
24224
0
        AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
24225
        // Check that traits expr is a constant array.
24226
0
        QualType TraitTy;
24227
0
        if (const ArrayType *Ty =
24228
0
                AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
24229
0
          if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
24230
0
            TraitTy = ConstArrayTy->getElementType();
24231
0
        if (TraitTy.isNull() ||
24232
0
            !(Context.hasSameUnqualifiedType(TraitTy,
24233
0
                                             DSAStack->getOMPAlloctraitT()) ||
24234
0
              Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
24235
0
                                         /*CompareUnqualified=*/true))) {
24236
0
          Diag(D.AllocatorTraits->getExprLoc(),
24237
0
               diag::err_omp_expected_array_alloctraits)
24238
0
              << AllocatorTraitsExpr->getType();
24239
0
          continue;
24240
0
        }
24241
        // Do not map by default allocator traits if it is a standalone
24242
        // variable.
24243
0
        if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
24244
0
          DSAStack->addUsesAllocatorsDecl(
24245
0
              DRE->getDecl(),
24246
0
              DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
24247
0
      }
24248
0
    }
24249
0
    OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
24250
0
    NewD.Allocator = AllocatorExpr;
24251
0
    NewD.AllocatorTraits = AllocatorTraitsExpr;
24252
0
    NewD.LParenLoc = D.LParenLoc;
24253
0
    NewD.RParenLoc = D.RParenLoc;
24254
0
  }
24255
0
  return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24256
0
                                         NewData);
24257
0
}
24258
24259
OMPClause *Sema::ActOnOpenMPAffinityClause(
24260
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
24261
0
    SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
24262
0
  SmallVector<Expr *, 8> Vars;
24263
0
  for (Expr *RefExpr : Locators) {
24264
0
    assert(RefExpr && "NULL expr in OpenMP shared clause.");
24265
0
    if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
24266
      // It will be analyzed later.
24267
0
      Vars.push_back(RefExpr);
24268
0
      continue;
24269
0
    }
24270
24271
0
    SourceLocation ELoc = RefExpr->getExprLoc();
24272
0
    Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
24273
24274
0
    if (!SimpleExpr->isLValue()) {
24275
0
      Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24276
0
          << 1 << 0 << RefExpr->getSourceRange();
24277
0
      continue;
24278
0
    }
24279
24280
0
    ExprResult Res;
24281
0
    {
24282
0
      Sema::TentativeAnalysisScope Trap(*this);
24283
0
      Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
24284
0
    }
24285
0
    if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
24286
0
        !isa<OMPArrayShapingExpr>(SimpleExpr)) {
24287
0
      Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24288
0
          << 1 << 0 << RefExpr->getSourceRange();
24289
0
      continue;
24290
0
    }
24291
0
    Vars.push_back(SimpleExpr);
24292
0
  }
24293
24294
0
  return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
24295
0
                                   EndLoc, Modifier, Vars);
24296
0
}
24297
24298
OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
24299
                                       SourceLocation KindLoc,
24300
                                       SourceLocation StartLoc,
24301
                                       SourceLocation LParenLoc,
24302
0
                                       SourceLocation EndLoc) {
24303
0
  if (Kind == OMPC_BIND_unknown) {
24304
0
    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
24305
0
        << getListOfPossibleValues(OMPC_bind, /*First=*/0,
24306
0
                                   /*Last=*/unsigned(OMPC_BIND_unknown))
24307
0
        << getOpenMPClauseName(OMPC_bind);
24308
0
    return nullptr;
24309
0
  }
24310
24311
0
  return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
24312
0
                               EndLoc);
24313
0
}
24314
24315
OMPClause *Sema::ActOnOpenMPXDynCGroupMemClause(Expr *Size,
24316
                                                SourceLocation StartLoc,
24317
                                                SourceLocation LParenLoc,
24318
0
                                                SourceLocation EndLoc) {
24319
0
  Expr *ValExpr = Size;
24320
0
  Stmt *HelperValStmt = nullptr;
24321
24322
  // OpenMP [2.5, Restrictions]
24323
  //  The ompx_dyn_cgroup_mem expression must evaluate to a positive integer
24324
  //  value.
24325
0
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_ompx_dyn_cgroup_mem,
24326
0
                                 /*StrictlyPositive=*/false))
24327
0
    return nullptr;
24328
24329
0
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
24330
0
  OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
24331
0
      DKind, OMPC_ompx_dyn_cgroup_mem, LangOpts.OpenMP);
24332
0
  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
24333
0
    ValExpr = MakeFullExpr(ValExpr).get();
24334
0
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
24335
0
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
24336
0
    HelperValStmt = buildPreInits(Context, Captures);
24337
0
  }
24338
24339
0
  return new (Context) OMPXDynCGroupMemClause(
24340
0
      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
24341
0
}
24342
24343
OMPClause *Sema::ActOnOpenMPDoacrossClause(
24344
    OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc,
24345
    SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
24346
0
    SourceLocation LParenLoc, SourceLocation EndLoc) {
24347
24348
0
  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
24349
0
      DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
24350
0
      DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
24351
0
      DepType != OMPC_DOACROSS_source_omp_cur_iteration &&
24352
0
      DepType != OMPC_DOACROSS_source) {
24353
0
    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
24354
0
        << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
24355
0
    return nullptr;
24356
0
  }
24357
24358
0
  SmallVector<Expr *, 8> Vars;
24359
0
  DSAStackTy::OperatorOffsetTy OpsOffs;
24360
0
  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
24361
0
  DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
24362
0
      *this,
24363
0
      DepType == OMPC_DOACROSS_source ||
24364
0
          DepType == OMPC_DOACROSS_source_omp_cur_iteration ||
24365
0
          DepType == OMPC_DOACROSS_sink_omp_cur_iteration,
24366
0
      VarList, DSAStack, EndLoc);
24367
0
  Vars = VarOffset.Vars;
24368
0
  OpsOffs = VarOffset.OpsOffs;
24369
0
  TotalDepCount = VarOffset.TotalDepCount;
24370
0
  auto *C = OMPDoacrossClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24371
0
                                      DepType, DepLoc, ColonLoc, Vars,
24372
0
                                      TotalDepCount.getZExtValue());
24373
0
  if (DSAStack->isParentOrderedRegion())
24374
0
    DSAStack->addDoacrossDependClause(C, OpsOffs);
24375
0
  return C;
24376
0
}
24377
24378
OMPClause *Sema::ActOnOpenMPXAttributeClause(ArrayRef<const Attr *> Attrs,
24379
                                             SourceLocation StartLoc,
24380
                                             SourceLocation LParenLoc,
24381
0
                                             SourceLocation EndLoc) {
24382
0
  return new (Context) OMPXAttributeClause(Attrs, StartLoc, LParenLoc, EndLoc);
24383
0
}
24384
24385
OMPClause *Sema::ActOnOpenMPXBareClause(SourceLocation StartLoc,
24386
0
                                        SourceLocation EndLoc) {
24387
0
  return new (Context) OMPXBareClause(StartLoc, EndLoc);
24388
0
}