Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/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
86.5M
    DSAVarData() = default;
82
    DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
83
               const Expr *RefExpr, DeclRefExpr *PrivateCopy,
84
               SourceLocation ImplicitDSALoc, unsigned Modifier,
85
               bool AppliedToPointee)
86
3.62k
        : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
87
3.62k
          PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
88
3.62k
          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
6.46k
    ReductionData() = default;
135
6.34k
    void set(BinaryOperatorKind BO, SourceRange RR) {
136
6.34k
      ReductionRange = RR;
137
6.34k
      ReductionOp = BO;
138
6.34k
    }
139
120
    void set(const Expr *RefExpr, SourceRange RR) {
140
120
      ReductionRange = RR;
141
120
      ReductionOp = RefExpr;
142
120
    }
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
1.63M
    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];
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
20
          : 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
543k
        : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
227
543k
          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
5.75M
  const_iterator begin() const {
252
5.75M
    return Stack.empty() ? 
const_iterator()365
253
5.75M
                         : 
Stack.back().first.rbegin() + IgnoredStackElements5.75M
;
254
5.75M
  }
255
123M
  const_iterator end() const {
256
123M
    return Stack.empty() ? 
const_iterator()365
:
Stack.back().first.rend()123M
;
257
123M
  }
258
  using iterator = StackTy::reverse_iterator;
259
5.19M
  iterator begin() {
260
5.19M
    return Stack.empty() ? 
iterator()0
261
5.19M
                         : Stack.back().first.rbegin() + IgnoredStackElements;
262
5.19M
  }
263
5.20M
  iterator end() {
264
5.20M
    return Stack.empty() ? 
iterator()0
: Stack.back().first.rend();
265
5.20M
  }
266
267
  // Convenience operations to get at the elements of the stack.
268
269
185M
  bool isStackEmpty() const {
270
185M
    return Stack.empty() ||
271
185M
           
Stack.back().second != CurrentNonCapturingFunctionScope185M
||
272
185M
           
Stack.back().first.size() <= IgnoredStackElements185M
;
273
185M
  }
274
141M
  size_t getStackSize() const {
275
141M
    return isStackEmpty() ? 
0513k
276
141M
                          : 
Stack.back().first.size() - IgnoredStackElements140M
;
277
141M
  }
278
279
92.0M
  SharingMapTy *getTopOfStackOrNull() {
280
92.0M
    size_t Size = getStackSize();
281
92.0M
    if (Size == 0)
282
511k
      return nullptr;
283
91.5M
    return &Stack.back().first[Size - 1];
284
92.0M
  }
285
70.7M
  const SharingMapTy *getTopOfStackOrNull() const {
286
70.7M
    return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
287
70.7M
  }
288
21.2M
  SharingMapTy &getTopOfStack() {
289
21.2M
    assert(!isStackEmpty() && "no current directive");
290
21.2M
    return *getTopOfStackOrNull();
291
21.2M
  }
292
18.3M
  const SharingMapTy &getTopOfStack() const {
293
18.3M
    return const_cast<DSAStackTy &>(*this).getTopOfStack();
294
18.3M
  }
295
296
2.02M
  SharingMapTy *getSecondOnStackOrNull() {
297
2.02M
    size_t Size = getStackSize();
298
2.02M
    if (Size <= 1)
299
429k
      return nullptr;
300
1.59M
    return &Stack.back().first[Size - 2];
301
2.02M
  }
302
1.96M
  const SharingMapTy *getSecondOnStackOrNull() const {
303
1.96M
    return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
304
1.96M
  }
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
25.1M
  SharingMapTy &getStackElemAtLevel(unsigned Level) {
313
25.1M
    assert(Level < getStackSize() && "no such stack element");
314
25.1M
    return Stack.back().first[Level];
315
25.1M
  }
316
24.9M
  const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
317
24.9M
    return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
318
24.9M
  }
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
90.9k
  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
346
347
  /// Sets omp_allocator_handle_t type.
348
1.03k
  void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
349
  /// Gets omp_allocator_handle_t type.
350
6.10k
  QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
351
  /// Sets omp_alloctrait_t type.
352
35
  void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
353
  /// Gets omp_alloctrait_t type.
354
98
  QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
355
  /// Sets the given default allocator.
356
  void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
357
9.32k
                    Expr *Allocator) {
358
9.32k
    OMPPredefinedAllocators[AllocatorKind] = Allocator;
359
9.32k
  }
360
  /// Returns the specified default allocator.
361
19.2k
  Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
362
19.2k
    return OMPPredefinedAllocators[AllocatorKind];
363
19.2k
  }
364
  /// Sets omp_depend_t type.
365
32
  void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
366
  /// Gets omp_depend_t type.
367
7.04k
  QualType getOMPDependT() const { return OMPDependT; }
368
369
  /// Sets omp_event_handle_t type.
370
15
  void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
371
  /// Gets omp_event_handle_t type.
372
254
  QualType getOMPEventHandleT() const { return OMPEventHandleT; }
373
374
14.7M
  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
375
822k
  OpenMPClauseKind getClauseParsingMode() const {
376
822k
    assert(isClauseParsingMode() && "Must be in clause parsing mode.");
377
822k
    return ClauseKindMode;
378
822k
  }
379
773k
  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
380
381
332k
  bool isBodyComplete() const {
382
332k
    const SharingMapTy *Top = getTopOfStackOrNull();
383
332k
    return Top && 
Top->BodyComplete304k
;
384
332k
  }
385
485k
  void setBodyComplete() { getTopOfStack().BodyComplete = true; }
386
387
486k
  bool isForceVarCapturing() const { return ForceCapturing; }
388
210k
  void setForceVarCapturing(bool V) { ForceCapturing = V; }
389
390
115k
  void setForceCaptureByReferenceInTargetExecutable(bool V) {
391
115k
    ForceCaptureByReferenceInTargetExecutable = V;
392
115k
  }
393
1.09M
  bool isForceCaptureByReferenceInTargetExecutable() const {
394
1.09M
    return ForceCaptureByReferenceInTargetExecutable;
395
1.09M
  }
396
397
  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
398
543k
            Scope *CurScope, SourceLocation Loc) {
399
543k
    assert(!IgnoredStackElements &&
400
543k
           "cannot change stack while ignoring elements");
401
543k
    if (Stack.empty() ||
402
543k
        
Stack.back().second != CurrentNonCapturingFunctionScope501k
)
403
41.7k
      Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
404
543k
    Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
405
543k
    Stack.back().first.back().DefaultAttrLoc = Loc;
406
543k
  }
407
408
543k
  void pop() {
409
543k
    assert(!IgnoredStackElements &&
410
543k
           "cannot change stack while ignoring elements");
411
543k
    assert(!Stack.back().first.empty() &&
412
543k
           "Data-sharing attributes stack is empty!");
413
543k
    Stack.back().first.pop_back();
414
543k
  }
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
2.20M
        : Self(Self), Active(false) {
425
2.20M
      if (Activate)
426
83.0k
        enable();
427
2.20M
    }
428
2.20M
    ~ParentDirectiveScope() { disable(); }
429
2.20M
    void disable() {
430
2.20M
      if (Active) {
431
83.0k
        --Self.IgnoredStackElements;
432
83.0k
        Active = false;
433
83.0k
      }
434
2.20M
    }
435
83.0k
    void enable() {
436
83.0k
      if (!Active) {
437
83.0k
        ++Self.IgnoredStackElements;
438
83.0k
        Active = true;
439
83.0k
      }
440
83.0k
    }
441
  };
442
443
  /// Marks that we're started loop parsing.
444
265k
  void loopInit() {
445
265k
    assert(isOpenMPLoopDirective(getCurrentDirective()) &&
446
265k
           "Expected loop-based directive.");
447
265k
    getTopOfStack().LoopStart = true;
448
265k
  }
449
  /// Start capturing of the variables in the loop context.
450
316k
  void loopStart() {
451
316k
    assert(isOpenMPLoopDirective(getCurrentDirective()) &&
452
316k
           "Expected loop-based directive.");
453
316k
    getTopOfStack().LoopStart = false;
454
316k
  }
455
  /// true, if variables are captured, false otherwise.
456
1.53M
  bool isLoopStarted() const {
457
1.53M
    assert(isOpenMPLoopDirective(getCurrentDirective()) &&
458
1.53M
           "Expected loop-based directive.");
459
1.53M
    return !getTopOfStack().LoopStart;
460
1.53M
  }
461
  /// Marks (or clears) declaration as possibly loop counter.
462
279k
  void resetPossibleLoopCounter(const Decl *D = nullptr) {
463
279k
    getTopOfStack().PossiblyLoopCounter = D ? 
D->getCanonicalDecl()54.6k
:
D224k
;
464
279k
  }
465
  /// Gets the possible loop counter decl.
466
3.22M
  const Decl *getPossiblyLoopCunter() const {
467
3.22M
    return getTopOfStack().PossiblyLoopCounter;
468
3.22M
  }
469
  /// Start new OpenMP region stack in new non-capturing function.
470
116k
  void pushFunction() {
471
116k
    assert(!IgnoredStackElements &&
472
116k
           "cannot change stack while ignoring elements");
473
116k
    const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
474
116k
    assert(!isa<CapturingScopeInfo>(CurFnScope));
475
116k
    CurrentNonCapturingFunctionScope = CurFnScope;
476
116k
  }
477
  /// Pop region stack for non-capturing function.
478
965k
  void popFunction(const FunctionScopeInfo *OldFSI) {
479
965k
    assert(!IgnoredStackElements &&
480
965k
           "cannot change stack while ignoring elements");
481
965k
    if (!Stack.empty() && 
Stack.back().second == OldFSI895k
) {
482
41.6k
      assert(Stack.back().first.empty());
483
41.6k
      Stack.pop_back();
484
41.6k
    }
485
965k
    CurrentNonCapturingFunctionScope = nullptr;
486
1.78M
    for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
487
1.78M
      if (!isa<CapturingScopeInfo>(FSI)) {
488
857k
        CurrentNonCapturingFunctionScope = FSI;
489
857k
        break;
490
857k
      }
491
1.78M
    }
492
965k
  }
493
494
95
  void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
495
95
    Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
496
95
  }
497
  const std::pair<const OMPCriticalDirective *, llvm::APSInt>
498
2.38k
  getCriticalWithHint(const DeclarationNameInfo &Name) const {
499
2.38k
    auto I = Criticals.find(Name.getAsString());
500
2.38k
    if (I != Criticals.end())
501
177
      return I->second;
502
2.20k
    return std::make_pair(nullptr, llvm::APSInt());
503
2.38k
  }
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
235
  void markDeclAsUsedInScanDirective(ValueDecl *D) {
537
235
    if (SharingMapTy *Stack = getSecondOnStackOrNull())
538
235
      Stack->UsedInScanDirective.insert(D);
539
235
  }
540
541
  /// Checks if the specified declaration was used in the inner scan directive.
542
301
  bool isUsedInScanDirective(ValueDecl *D) const {
543
301
    if (const SharingMapTy *Stack = getTopOfStackOrNull())
544
301
      return Stack->UsedInScanDirective.contains(D);
545
0
    return false;
546
301
  }
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
128k
  Expr *getTaskgroupReductionRef() const {
576
128k
    assert((getTopOfStack().Directive == OMPD_taskgroup ||
577
128k
            ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
578
128k
              isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
579
128k
             !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
580
128k
           "taskgroup reference expression requested for non taskgroup or "
581
128k
           "parallel/worksharing directive.");
582
128k
    return getTopOfStack().TaskgroupReductionRef;
583
128k
  }
584
  /// Checks if the given \p VD declaration is actually a taskgroup reduction
585
  /// descriptor variable at the \p Level of OpenMP regions.
586
867k
  bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
587
867k
    return getStackElemAtLevel(Level).TaskgroupReductionRef &&
588
867k
           cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
589
37.7k
                   ->getDecl() == VD;
590
867k
  }
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
27.0M
  OpenMPDirectiveKind getCurrentDirective() const {
640
27.0M
    const SharingMapTy *Top = getTopOfStackOrNull();
641
27.0M
    return Top ? 
Top->Directive26.6M
:
OMPD_unknown337k
;
642
27.0M
  }
643
38.2k
  OpenMPDirectiveKind getMappedDirective() const {
644
38.2k
    const SharingMapTy *Top = getTopOfStackOrNull();
645
38.2k
    return Top ? Top->MappedDirective : 
OMPD_unknown0
;
646
38.2k
  }
647
90
  void setCurrentDirective(OpenMPDirectiveKind NewDK) {
648
90
    SharingMapTy *Top = getTopOfStackOrNull();
649
90
    assert(Top &&
650
90
           "Before calling setCurrentDirective Top of Stack not to be NULL.");
651
    // Store the old into MappedDirective & assign argument NewDK to Directive.
652
90
    Top->Directive = NewDK;
653
90
  }
654
97
  void setMappedDirective(OpenMPDirectiveKind NewDK) {
655
97
    SharingMapTy *Top = getTopOfStackOrNull();
656
97
    assert(Top &&
657
97
           "Before calling setMappedDirective Top of Stack not to be NULL.");
658
    // Store the old into MappedDirective & assign argument NewDK to Directive.
659
97
    Top->MappedDirective = NewDK;
660
97
  }
661
  /// Returns directive kind at specified level.
662
2.37M
  OpenMPDirectiveKind getDirective(unsigned Level) const {
663
2.37M
    assert(!isStackEmpty() && "No directive at specified level.");
664
2.37M
    return getStackElemAtLevel(Level).Directive;
665
2.37M
  }
666
  /// Returns the capture region at the specified level.
667
  OpenMPDirectiveKind getCaptureRegion(unsigned Level,
668
13.0k
                                       unsigned OpenMPCaptureLevel) const {
669
13.0k
    SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
670
13.0k
    getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
671
13.0k
    return CaptureRegions[OpenMPCaptureLevel];
672
13.0k
  }
673
  /// Returns parent directive.
674
1.71M
  OpenMPDirectiveKind getParentDirective() const {
675
1.71M
    const SharingMapTy *Parent = getSecondOnStackOrNull();
676
1.71M
    return Parent ? 
Parent->Directive1.44M
:
OMPD_unknown265k
;
677
1.71M
  }
678
679
  /// Add requires decl to internal vector
680
238
  void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
681
682
  /// Checks if the defined 'requires' directive has specified type of clause.
683
489k
  template <typename ClauseType> bool hasRequiresDeclWithClause() const {
684
489k
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
36.3k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
36.3k
        return isa<ClauseType>(C);
687
36.3k
      });
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPDynamicAllocatorsClause>() const::'lambda'(clang::OMPRequiresDecl const*)::operator()(clang::OMPRequiresDecl const*) const::'lambda'(clang::OMPClause const*)::operator()(clang::OMPClause const*) const
Line
Count
Source
685
8.86k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
8.86k
        return isa<ClauseType>(C);
687
8.86k
      });
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedSharedMemoryClause>() const::'lambda'(clang::OMPRequiresDecl const*)::operator()(clang::OMPRequiresDecl const*) const::'lambda'(clang::OMPClause const*)::operator()(clang::OMPClause const*) const
Line
Count
Source
685
9.17k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
9.17k
        return isa<ClauseType>(C);
687
9.17k
      });
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedAddressClause>() const::'lambda'(clang::OMPRequiresDecl const*)::operator()(clang::OMPRequiresDecl const*) const::'lambda'(clang::OMPClause const*)::operator()(clang::OMPClause const*) const
Line
Count
Source
685
9.14k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
9.14k
        return isa<ClauseType>(C);
687
9.14k
      });
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPReverseOffloadClause>() const::'lambda'(clang::OMPRequiresDecl const*)::operator()(clang::OMPRequiresDecl const*) const::'lambda'(clang::OMPClause const*)::operator()(clang::OMPClause const*) const
Line
Count
Source
685
9.16k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
9.16k
        return isa<ClauseType>(C);
687
9.16k
      });
688
36.3k
    });
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPDynamicAllocatorsClause>() const::'lambda'(clang::OMPRequiresDecl const*)::operator()(clang::OMPRequiresDecl const*) const
Line
Count
Source
684
8.86k
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
8.86k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
8.86k
        return isa<ClauseType>(C);
687
8.86k
      });
688
8.86k
    });
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedSharedMemoryClause>() const::'lambda'(clang::OMPRequiresDecl const*)::operator()(clang::OMPRequiresDecl const*) const
Line
Count
Source
684
9.17k
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
9.17k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
9.17k
        return isa<ClauseType>(C);
687
9.17k
      });
688
9.17k
    });
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedAddressClause>() const::'lambda'(clang::OMPRequiresDecl const*)::operator()(clang::OMPRequiresDecl const*) const
Line
Count
Source
684
9.14k
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
9.14k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
9.14k
        return isa<ClauseType>(C);
687
9.14k
      });
688
9.14k
    });
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPReverseOffloadClause>() const::'lambda'(clang::OMPRequiresDecl const*)::operator()(clang::OMPRequiresDecl const*) const
Line
Count
Source
684
9.16k
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
9.16k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
9.16k
        return isa<ClauseType>(C);
687
9.16k
      });
688
9.16k
    });
689
489k
  }
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPDynamicAllocatorsClause>() const
Line
Count
Source
683
122k
  template <typename ClauseType> bool hasRequiresDeclWithClause() const {
684
122k
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
122k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
122k
        return isa<ClauseType>(C);
687
122k
      });
688
122k
    });
689
122k
  }
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedSharedMemoryClause>() const
Line
Count
Source
683
124k
  template <typename ClauseType> bool hasRequiresDeclWithClause() const {
684
124k
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
124k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
124k
        return isa<ClauseType>(C);
687
124k
      });
688
124k
    });
689
124k
  }
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPUnifiedAddressClause>() const
Line
Count
Source
683
120k
  template <typename ClauseType> bool hasRequiresDeclWithClause() const {
684
120k
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
120k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
120k
        return isa<ClauseType>(C);
687
120k
      });
688
120k
    });
689
120k
  }
SemaOpenMP.cpp:bool (anonymous namespace)::DSAStackTy::hasRequiresDeclWithClause<clang::OMPReverseOffloadClause>() const
Line
Count
Source
683
120k
  template <typename ClauseType> bool hasRequiresDeclWithClause() const {
684
120k
    return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685
120k
      return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686
120k
        return isa<ClauseType>(C);
687
120k
      });
688
120k
    });
689
120k
  }
690
691
  /// Checks for a duplicate clause amongst previously declared requires
692
  /// directives
693
264
  bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
694
264
    bool IsDuplicate = false;
695
268
    for (OMPClause *CNew : ClauseList) {
696
268
      for (const OMPRequiresDecl *D : RequiresDecls) {
697
208
        for (const OMPClause *CPrev : D->clauselists()) {
698
208
          if (CNew->getClauseKind() == CPrev->getClauseKind()) {
699
30
            SemaRef.Diag(CNew->getBeginLoc(),
700
30
                         diag::err_omp_requires_clause_redeclaration)
701
30
                << getOpenMPClauseName(CNew->getClauseKind());
702
30
            SemaRef.Diag(CPrev->getBeginLoc(),
703
30
                         diag::note_omp_requires_previous_clause)
704
30
                << getOpenMPClauseName(CPrev->getClauseKind());
705
30
            IsDuplicate = true;
706
30
          }
707
208
        }
708
208
      }
709
268
    }
710
264
    return IsDuplicate;
711
264
  }
712
713
  /// Add location of previously encountered target to internal vector
714
111k
  void addTargetDirLocation(SourceLocation LocStart) {
715
111k
    TargetLocations.push_back(LocStart);
716
111k
  }
717
718
  /// Add location for the first encountered atomicc directive.
719
20.4k
  void addAtomicDirectiveLoc(SourceLocation Loc) {
720
20.4k
    if (AtomicLocation.isInvalid())
721
124
      AtomicLocation = Loc;
722
20.4k
  }
723
724
  /// Returns the location of the first encountered atomic directive in the
725
  /// module.
726
264
  SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
727
728
  // Return previously encountered target region locations.
729
264
  ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
730
264
    return TargetLocations;
731
264
  }
732
733
  /// Set default data sharing attribute to none.
734
1.38k
  void setDefaultDSANone(SourceLocation Loc) {
735
1.38k
    getTopOfStack().DefaultAttr = DSA_none;
736
1.38k
    getTopOfStack().DefaultAttrLoc = Loc;
737
1.38k
  }
738
  /// Set default data sharing attribute to shared.
739
898
  void setDefaultDSAShared(SourceLocation Loc) {
740
898
    getTopOfStack().DefaultAttr = DSA_shared;
741
898
    getTopOfStack().DefaultAttrLoc = Loc;
742
898
  }
743
  /// Set default data sharing attribute to private.
744
96
  void setDefaultDSAPrivate(SourceLocation Loc) {
745
96
    getTopOfStack().DefaultAttr = DSA_private;
746
96
    getTopOfStack().DefaultAttrLoc = Loc;
747
96
  }
748
  /// Set default data sharing attribute to firstprivate.
749
123
  void setDefaultDSAFirstPrivate(SourceLocation Loc) {
750
123
    getTopOfStack().DefaultAttr = DSA_firstprivate;
751
123
    getTopOfStack().DefaultAttrLoc = Loc;
752
123
  }
753
  /// Set default data mapping attribute to Modifier:Kind
754
  void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
755
4.00k
                         OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
756
4.00k
    DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
757
4.00k
    DMI.ImplicitBehavior = M;
758
4.00k
    DMI.SLoc = Loc;
759
4.00k
  }
760
  /// Check whether the implicit-behavior has been set in defaultmap
761
2.67k
  bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
762
2.67k
    if (VariableCategory == OMPC_DEFAULTMAP_unknown)
763
624
      return getTopOfStack()
764
624
                     .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
765
624
                     .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
766
624
             getTopOfStack()
767
624
                     .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
768
624
                     .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
769
624
             getTopOfStack()
770
624
                     .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
771
624
                     .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
772
2.05k
    return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
773
2.05k
           OMPC_DEFAULTMAP_MODIFIER_unknown;
774
2.67k
  }
775
776
2.79k
  ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
777
2.79k
    return ConstructTraits;
778
2.79k
  }
779
  void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
780
1.06M
                            bool ScopeEntry) {
781
1.06M
    if (ScopeEntry)
782
534k
      ConstructTraits.append(Traits.begin(), Traits.end());
783
534k
    else
784
793k
      
for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits))534k
{
785
793k
        llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
786
793k
        assert(Top == Trait && "Something left a trait on the stack!");
787
793k
        (void)Trait;
788
793k
        (void)Top;
789
793k
      }
790
1.06M
  }
791
792
0
  DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
793
0
    return getStackSize() <= Level ? DSA_unspecified
794
0
                                   : getStackElemAtLevel(Level).DefaultAttr;
795
0
  }
796
4.24M
  DefaultDataSharingAttributes getDefaultDSA() const {
797
4.24M
    return isStackEmpty() ? 
DSA_unspecified0
: getTopOfStack().DefaultAttr;
798
4.24M
  }
799
632
  SourceLocation getDefaultDSALocation() const {
800
632
    return isStackEmpty() ? 
SourceLocation()0
: getTopOfStack().DefaultAttrLoc;
801
632
  }
802
  OpenMPDefaultmapClauseModifier
803
347k
  getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
804
347k
    return isStackEmpty()
805
347k
               ? 
OMPC_DEFAULTMAP_MODIFIER_unknown0
806
347k
               : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
807
347k
  }
808
  OpenMPDefaultmapClauseModifier
809
  getDefaultmapModifierAtLevel(unsigned Level,
810
924k
                               OpenMPDefaultmapClauseKind Kind) const {
811
924k
    return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
812
924k
  }
813
  bool isDefaultmapCapturedByRef(unsigned Level,
814
702k
                                 OpenMPDefaultmapClauseKind Kind) const {
815
702k
    OpenMPDefaultmapClauseModifier M =
816
702k
        getDefaultmapModifierAtLevel(Level, Kind);
817
702k
    if (Kind == OMPC_DEFAULTMAP_scalar || 
Kind == OMPC_DEFAULTMAP_pointer113k
) {
818
702k
      return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
819
702k
             
(M == OMPC_DEFAULTMAP_MODIFIER_to)702k
||
820
702k
             
(M == OMPC_DEFAULTMAP_MODIFIER_from)702k
||
821
702k
             
(M == OMPC_DEFAULTMAP_MODIFIER_tofrom)701k
;
822
702k
    }
823
0
    return true;
824
702k
  }
825
  static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
826
301k
                                     OpenMPDefaultmapClauseKind Kind) {
827
301k
    switch (Kind) {
828
204k
    case OMPC_DEFAULTMAP_scalar:
829
233k
    case OMPC_DEFAULTMAP_pointer:
830
233k
      return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
831
233k
             
(M == OMPC_DEFAULTMAP_MODIFIER_firstprivate)1.74k
||
832
233k
             
(M == OMPC_DEFAULTMAP_MODIFIER_default)1.69k
;
833
67.9k
    case OMPC_DEFAULTMAP_aggregate:
834
67.9k
      return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
835
0
    default:
836
0
      break;
837
301k
    }
838
0
    llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
839
0
  }
840
  bool mustBeFirstprivateAtLevel(unsigned Level,
841
221k
                                 OpenMPDefaultmapClauseKind Kind) const {
842
221k
    OpenMPDefaultmapClauseModifier M =
843
221k
        getDefaultmapModifierAtLevel(Level, Kind);
844
221k
    return mustBeFirstprivateBase(M, Kind);
845
221k
  }
846
79.5k
  bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
847
79.5k
    OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
848
79.5k
    return mustBeFirstprivateBase(M, Kind);
849
79.5k
  }
850
851
  /// Checks if the specified variable is a threadprivate.
852
3.43M
  bool isThreadPrivate(VarDecl *D) {
853
3.43M
    const DSAVarData DVar = getTopDSA(D, false);
854
3.43M
    return isOpenMPThreadPrivate(DVar.CKind);
855
3.43M
  }
856
857
  /// Marks current region as ordered (it has an 'ordered' clause).
858
  void setOrderedRegion(bool IsOrdered, const Expr *Param,
859
1.41k
                        OMPOrderedClause *Clause) {
860
1.41k
    if (IsOrdered)
861
1.41k
      getTopOfStack().OrderedRegion.emplace(Param, Clause);
862
0
    else
863
0
      getTopOfStack().OrderedRegion.reset();
864
1.41k
  }
865
  /// Returns true, if region is ordered (has associated 'ordered' clause),
866
  /// false - otherwise.
867
165k
  bool isOrderedRegion() const {
868
165k
    if (const SharingMapTy *Top = getTopOfStackOrNull())
869
165k
      return Top->OrderedRegion.has_value();
870
0
    return false;
871
165k
  }
872
  /// Returns optional parameter for the ordered region.
873
2.78k
  std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
874
2.78k
    if (const SharingMapTy *Top = getTopOfStackOrNull())
875
2.78k
      if (Top->OrderedRegion)
876
2.78k
        return *Top->OrderedRegion;
877
0
    return std::make_pair(nullptr, nullptr);
878
2.78k
  }
879
  /// Returns true, if parent region is ordered (has associated
880
  /// 'ordered' clause), false - otherwise.
881
2.73k
  bool isParentOrderedRegion() const {
882
2.73k
    if (const SharingMapTy *Parent = getSecondOnStackOrNull())
883
2.71k
      return Parent->OrderedRegion.has_value();
884
12
    return false;
885
2.73k
  }
886
  /// Returns optional parameter for the ordered region.
887
  std::pair<const Expr *, OMPOrderedClause *>
888
3.36k
  getParentOrderedRegionParam() const {
889
3.36k
    if (const SharingMapTy *Parent = getSecondOnStackOrNull())
890
2.49k
      if (Parent->OrderedRegion)
891
2.48k
        return *Parent->OrderedRegion;
892
889
    return std::make_pair(nullptr, nullptr);
893
3.36k
  }
894
  /// Marks current region as having an 'order' clause.
895
480
  void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
896
480
    getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
897
480
  }
898
  /// Returns true, if parent region is order (has associated
899
  /// 'order' clause), false - otherwise.
900
241k
  bool isParentOrderConcurrent() const {
901
241k
    if (const SharingMapTy *Parent = getSecondOnStackOrNull())
902
79.8k
      return Parent->RegionHasOrderConcurrent;
903
161k
    return false;
904
241k
  }
905
  /// Marks current region as nowait (it has a 'nowait' clause).
906
1.82k
  void setNowaitRegion(bool IsNowait = true) {
907
1.82k
    getTopOfStack().NowaitRegion = IsNowait;
908
1.82k
  }
909
  /// Returns true, if parent region is nowait (has associated
910
  /// 'nowait' clause), false - otherwise.
911
965
  bool isParentNowaitRegion() const {
912
965
    if (const SharingMapTy *Parent = getSecondOnStackOrNull())
913
965
      return Parent->NowaitRegion;
914
0
    return false;
915
965
  }
916
  /// Marks current region as untied (it has a 'untied' clause).
917
148
  void setUntiedRegion(bool IsUntied = true) {
918
148
    getTopOfStack().UntiedRegion = IsUntied;
919
148
  }
920
  /// Return true if current region is untied.
921
50
  bool isUntiedRegion() const {
922
50
    const SharingMapTy *Top = getTopOfStackOrNull();
923
50
    return Top ? Top->UntiedRegion : 
false0
;
924
50
  }
925
  /// Marks parent region as cancel region.
926
1.95k
  void setParentCancelRegion(bool Cancel = true) {
927
1.95k
    if (SharingMapTy *Parent = getSecondOnStackOrNull())
928
1.95k
      Parent->CancelRegion |= Cancel;
929
1.95k
  }
930
  /// Return true if current region has inner cancel construct.
931
145k
  bool isCancelRegion() const {
932
145k
    const SharingMapTy *Top = getTopOfStackOrNull();
933
145k
    return Top ? Top->CancelRegion : 
false0
;
934
145k
  }
935
936
  /// Mark that parent region already has scan directive.
937
173
  void setParentHasScanDirective(SourceLocation Loc) {
938
173
    if (SharingMapTy *Parent = getSecondOnStackOrNull())
939
173
      Parent->PrevScanLocation = Loc;
940
173
  }
941
  /// Return true if current region has inner cancel construct.
942
177
  bool doesParentHasScanDirective() const {
943
177
    const SharingMapTy *Top = getSecondOnStackOrNull();
944
177
    return Top ? Top->PrevScanLocation.isValid() : 
false0
;
945
177
  }
946
  /// Return true if current region has inner cancel construct.
947
4
  SourceLocation getParentScanDirectiveLoc() const {
948
4
    const SharingMapTy *Top = getSecondOnStackOrNull();
949
4
    return Top ? Top->PrevScanLocation : 
SourceLocation()0
;
950
4
  }
951
  /// Mark that parent region already has ordered directive.
952
1.28k
  void setParentHasOrderedDirective(SourceLocation Loc) {
953
1.28k
    if (SharingMapTy *Parent = getSecondOnStackOrNull())
954
420
      Parent->PrevOrderedLocation = Loc;
955
1.28k
  }
956
  /// Return true if current region has inner ordered construct.
957
1.29k
  bool doesParentHasOrderedDirective() const {
958
1.29k
    const SharingMapTy *Top = getSecondOnStackOrNull();
959
1.29k
    return Top ? 
Top->PrevOrderedLocation.isValid()434
:
false862
;
960
1.29k
  }
961
  /// Returns the location of the previously specified ordered directive.
962
14
  SourceLocation getParentOrderedDirectiveLoc() const {
963
14
    const SharingMapTy *Top = getSecondOnStackOrNull();
964
14
    return Top ? Top->PrevOrderedLocation : 
SourceLocation()0
;
965
14
  }
966
967
  /// Set collapse value for the region.
968
267k
  void setAssociatedLoops(unsigned Val) {
969
267k
    getTopOfStack().AssociatedLoops = Val;
970
267k
    if (Val > 1)
971
5.53k
      getTopOfStack().HasMutipleLoops = true;
972
267k
  }
973
  /// Return collapse value for region.
974
3.28M
  unsigned getAssociatedLoops() const {
975
3.28M
    const SharingMapTy *Top = getTopOfStackOrNull();
976
3.28M
    return Top ? 
Top->AssociatedLoops3.28M
:
0589
;
977
3.28M
  }
978
  /// Returns true if the construct is associated with multiple loops.
979
149k
  bool hasMutipleLoops() const {
980
149k
    const SharingMapTy *Top = getTopOfStackOrNull();
981
149k
    return Top ? Top->HasMutipleLoops : 
false0
;
982
149k
  }
983
984
  /// Marks current target region as one with closely nested teams
985
  /// region.
986
52.4k
  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
987
52.4k
    if (SharingMapTy *Parent = getSecondOnStackOrNull())
988
52.0k
      Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
989
52.4k
  }
990
  /// Returns true, if current region has closely nested teams region.
991
73.1k
  bool hasInnerTeamsRegion() const {
992
73.1k
    return getInnerTeamsRegionLoc().isValid();
993
73.1k
  }
994
  /// Returns location of the nested teams region (if any).
995
73.2k
  SourceLocation getInnerTeamsRegionLoc() const {
996
73.2k
    const SharingMapTy *Top = getTopOfStackOrNull();
997
73.2k
    return Top ? Top->InnerTeamsRegionLoc : 
SourceLocation()0
;
998
73.2k
  }
999
1000
36.7M
  Scope *getCurScope() const {
1001
36.7M
    const SharingMapTy *Top = getTopOfStackOrNull();
1002
36.7M
    return Top ? 
Top->CurScope36.7M
:
nullptr10
;
1003
36.7M
  }
1004
534k
  void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
1005
913k
  SourceLocation getConstructLoc() const {
1006
913k
    const SharingMapTy *Top = getTopOfStackOrNull();
1007
913k
    return Top ? Top->ConstructLoc : 
SourceLocation()0
;
1008
913k
  }
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
337k
          Check) const {
1018
337k
    if (isStackEmpty())
1019
0
      return false;
1020
337k
    auto SI = begin();
1021
337k
    auto SE = end();
1022
1023
337k
    if (SI == SE)
1024
0
      return false;
1025
1026
337k
    if (CurrentRegionOnly)
1027
297k
      SE = std::next(SI);
1028
40.2k
    else
1029
40.2k
      std::advance(SI, 1);
1030
1031
645k
    for (; SI != SE; 
++SI307k
) {
1032
317k
      auto MI = SI->MappedExprComponents.find(VD);
1033
317k
      if (MI != SI->MappedExprComponents.end())
1034
14.3k
        for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1035
14.3k
             MI->second.Components)
1036
14.5k
          if (Check(L, MI->second.Kind))
1037
9.33k
            return true;
1038
317k
    }
1039
328k
    return false;
1040
337k
  }
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
1.41M
          Check) const {
1050
1.41M
    if (getStackSize() <= Level)
1051
0
      return false;
1052
1053
1.41M
    const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1054
1.41M
    auto MI = StackElem.MappedExprComponents.find(VD);
1055
1.41M
    if (MI != StackElem.MappedExprComponents.end())
1056
43.0k
      for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1057
43.0k
           MI->second.Components)
1058
43.1k
        if (Check(L, MI->second.Kind))
1059
21.6k
          return true;
1060
1.39M
    return false;
1061
1.41M
  }
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
59.7k
      OpenMPClauseKind WhereFoundClauseKind) {
1069
59.7k
    MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1070
    // Create new entry and append the new components there.
1071
59.7k
    MEC.Components.resize(MEC.Components.size() + 1);
1072
59.7k
    MEC.Components.back().append(Components.begin(), Components.end());
1073
59.7k
    MEC.Kind = WhereFoundClauseKind;
1074
59.7k
  }
1075
1076
1.33M
  unsigned getNestingLevel() const {
1077
1.33M
    assert(!isStackEmpty());
1078
1.33M
    return getStackSize() - 1;
1079
1.33M
  }
1080
629
  void addDoacrossDependClause(OMPClause *C, const OperatorOffsetTy &OpsOffs) {
1081
629
    SharingMapTy *Parent = getSecondOnStackOrNull();
1082
629
    assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1083
629
    Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1084
629
  }
1085
  llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
1086
1.15k
  getDoacrossDependClauses() const {
1087
1.15k
    const SharingMapTy &StackElem = getTopOfStack();
1088
1.15k
    if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1089
1.15k
      const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1090
1.15k
      return llvm::make_range(Ref.begin(), Ref.end());
1091
1.15k
    }
1092
0
    return llvm::make_range(StackElem.DoacrossDepends.end(),
1093
0
                            StackElem.DoacrossDepends.end());
1094
1.15k
  }
1095
1096
  // Store types of classes which have been explicitly mapped
1097
123
  void addMappedClassesQualTypes(QualType QT) {
1098
123
    SharingMapTy &StackElem = getTopOfStack();
1099
123
    StackElem.MappedClassesQualTypes.insert(QT);
1100
123
  }
1101
1102
  // Return set of mapped classes types
1103
1.60k
  bool isClassPreviouslyMapped(QualType QT) const {
1104
1.60k
    const SharingMapTy &StackElem = getTopOfStack();
1105
1.60k
    return StackElem.MappedClassesQualTypes.contains(QT);
1106
1.60k
  }
1107
1108
  /// Adds global declare target to the parent target region.
1109
8
  void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1110
8
    assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1111
8
               E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1112
8
           "Expected declare target link global.");
1113
16
    
for (auto &Elem : *this)8
{
1114
16
      if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1115
8
        Elem.DeclareTargetLinkVarDecls.push_back(E);
1116
8
        return;
1117
8
      }
1118
16
    }
1119
8
  }
1120
1121
  /// Returns the list of globals with declare target link if current directive
1122
  /// is target.
1123
124k
  ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1124
124k
    assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1125
124k
           "Expected target executable directive.");
1126
124k
    return getTopOfStack().DeclareTargetLinkVarDecls;
1127
124k
  }
1128
1129
  /// Adds list of allocators expressions.
1130
2.10k
  void addInnerAllocatorExpr(Expr *E) {
1131
2.10k
    getTopOfStack().InnerUsedAllocators.push_back(E);
1132
2.10k
  }
1133
  /// Return list of used allocators.
1134
486k
  ArrayRef<Expr *> getInnerAllocators() const {
1135
486k
    return getTopOfStack().InnerUsedAllocators;
1136
486k
  }
1137
  /// Marks the declaration as implicitly firstprivate nin the task-based
1138
  /// regions.
1139
171k
  void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1140
171k
    getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1141
171k
  }
1142
  /// Checks if the decl is implicitly firstprivate in the task-based region.
1143
408k
  bool isImplicitTaskFirstprivate(Decl *D) const {
1144
408k
    return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1145
408k
  }
1146
1147
  /// Marks decl as used in uses_allocators clause as the allocator.
1148
541
  void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1149
541
    getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1150
541
  }
1151
  /// Checks if specified decl is used in uses allocator clause as the
1152
  /// allocator.
1153
  std::optional<UsesAllocatorsDeclKind>
1154
2.50M
  isUsesAllocatorsDecl(unsigned Level, const Decl *D) const {
1155
2.50M
    const SharingMapTy &StackElem = getTopOfStack();
1156
2.50M
    auto I = StackElem.UsesAllocatorsDecls.find(D);
1157
2.50M
    if (I == StackElem.UsesAllocatorsDecls.end())
1158
2.50M
      return std::nullopt;
1159
1.09k
    return I->getSecond();
1160
2.50M
  }
1161
  std::optional<UsesAllocatorsDeclKind>
1162
553k
  isUsesAllocatorsDecl(const Decl *D) const {
1163
553k
    const SharingMapTy &StackElem = getTopOfStack();
1164
553k
    auto I = StackElem.UsesAllocatorsDecls.find(D);
1165
553k
    if (I == StackElem.UsesAllocatorsDecls.end())
1166
552k
      return std::nullopt;
1167
521
    return I->getSecond();
1168
553k
  }
1169
1170
377
  void addDeclareMapperVarRef(Expr *Ref) {
1171
377
    SharingMapTy &StackElem = getTopOfStack();
1172
377
    StackElem.DeclareMapperVar = Ref;
1173
377
  }
1174
1.93M
  const Expr *getDeclareMapperVarRef() const {
1175
1.93M
    const SharingMapTy *Top = getTopOfStackOrNull();
1176
1.93M
    return Top ? 
Top->DeclareMapperVar1.79M
:
nullptr145k
;
1177
1.93M
  }
1178
1179
  /// Add a new iterator variable.
1180
12
  void addIteratorVarDecl(VarDecl *VD) {
1181
12
    SharingMapTy &StackElem = getTopOfStack();
1182
12
    StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl());
1183
12
  }
1184
  /// Check if variable declaration is an iterator VarDecl.
1185
10
  bool isIteratorVarDecl(const VarDecl *VD) const {
1186
10
    const SharingMapTy *Top = getTopOfStackOrNull();
1187
10
    if (!Top)
1188
0
      return false;
1189
1190
10
    return llvm::is_contained(Top->IteratorVarDecls, VD->getCanonicalDecl());
1191
10
  }
1192
  /// get captured field from ImplicitDefaultFirstprivateFDs
1193
3.23k
  VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
1194
3.23k
    const_iterator I = begin();
1195
3.23k
    const_iterator EndI = end();
1196
3.23k
    size_t StackLevel = getStackSize();
1197
7.67k
    for (; I != EndI; 
++I4.43k
) {
1198
4.57k
      if (I->DefaultAttr == DSA_firstprivate || 
I->DefaultAttr == DSA_private4.49k
)
1199
136
        break;
1200
4.43k
      StackLevel--;
1201
4.43k
    }
1202
3.23k
    assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1203
3.23k
    if (I == EndI)
1204
3.09k
      return nullptr;
1205
136
    for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1206
110
      if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1207
110
        return IFD.VD;
1208
26
    return nullptr;
1209
136
  }
1210
  /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
1211
421k
  bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
1212
421k
    const_iterator I = begin();
1213
421k
    const_iterator EndI = end();
1214
1.07M
    for (; I != EndI; 
++I650k
)
1215
650k
      if (I->DefaultAttr == DSA_firstprivate || 
I->DefaultAttr == DSA_private650k
)
1216
318
        break;
1217
421k
    if (I == EndI)
1218
420k
      return false;
1219
318
    for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1220
191
      if (IFD.VD == VD)
1221
146
        return true;
1222
172
    return false;
1223
318
  }
1224
  /// Store capture FD info in ImplicitDefaultFirstprivateFDs
1225
20
  void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
1226
20
    iterator I = begin();
1227
20
    const_iterator EndI = end();
1228
20
    size_t StackLevel = getStackSize();
1229
20
    for (; I != EndI; 
++I0
) {
1230
20
      if (I->DefaultAttr == DSA_private || 
I->DefaultAttr == DSA_firstprivate10
) {
1231
20
        I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1232
20
        break;
1233
20
      }
1234
0
      StackLevel--;
1235
0
    }
1236
20
    assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1237
20
  }
1238
};
1239
1240
54.8M
bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1241
54.8M
  return isOpenMPParallelDirective(DKind) || 
isOpenMPTeamsDirective(DKind)50.4M
;
1242
54.8M
}
1243
1244
53.1M
bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1245
53.1M
  return isImplicitTaskingRegion(DKind) || 
isOpenMPTaskingDirective(DKind)47.0M
||
1246
53.1M
         
DKind == OMPD_unknown16.5M
;
1247
53.1M
}
1248
1249
} // namespace
1250
1251
1.15M
static const Expr *getExprAsWritten(const Expr *E) {
1252
1.15M
  if (const auto *FE = dyn_cast<FullExpr>(E))
1253
343
    E = FE->getSubExpr();
1254
1255
1.15M
  if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1256
0
    E = MTE->getSubExpr();
1257
1258
1.15M
  while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1259
22
    E = Binder->getSubExpr();
1260
1261
1.15M
  if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1262
356k
    E = ICE->getSubExprAsWritten();
1263
1.15M
  return E->IgnoreParens();
1264
1.15M
}
1265
1266
457k
static Expr *getExprAsWritten(Expr *E) {
1267
457k
  return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1268
457k
}
1269
1270
71.6M
static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1271
71.6M
  if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1272
238k
    if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1273
52.0k
      D = ME->getMemberDecl();
1274
71.6M
  const auto *VD = dyn_cast<VarDecl>(D);
1275
71.6M
  const auto *FD = dyn_cast<FieldDecl>(D);
1276
71.6M
  if (VD != nullptr) {
1277
71.4M
    VD = VD->getCanonicalDecl();
1278
71.4M
    D = VD;
1279
71.4M
  } else {
1280
178k
    assert(FD);
1281
178k
    FD = FD->getCanonicalDecl();
1282
178k
    D = FD;
1283
178k
  }
1284
71.6M
  return D;
1285
71.6M
}
1286
1287
59.5M
static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1288
59.5M
  return const_cast<ValueDecl *>(
1289
59.5M
      getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1290
59.5M
}
1291
1292
DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1293
46.4M
                                          ValueDecl *D) const {
1294
46.4M
  D = getCanonicalDecl(D);
1295
46.4M
  auto *VD = dyn_cast<VarDecl>(D);
1296
46.4M
  const auto *FD = dyn_cast<FieldDecl>(D);
1297
46.4M
  DSAVarData DVar;
1298
46.4M
  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
5.79M
    if (VD && 
!VD->isFunctionOrMethodVarDecl()5.79M
&&
!isa<ParmVarDecl>(VD)3.66M
)
1305
1.50M
      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
5.79M
    if (VD && 
VD->hasGlobalStorage()5.79M
)
1312
1.53M
      DVar.CKind = OMPC_shared;
1313
1314
    // Non-static data members are shared by default.
1315
5.79M
    if (FD)
1316
6.18k
      DVar.CKind = OMPC_shared;
1317
1318
5.79M
    return DVar;
1319
5.79M
  }
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
40.6M
  if (VD && 
isOpenMPLocal(VD, Iter)40.6M
&&
VD->isLocalVarDecl()29.7k
&&
1326
40.6M
      
(27.8k
VD->getStorageClass() == SC_Auto27.8k
||
VD->getStorageClass() == SC_None27.8k
)) {
1327
27.8k
    DVar.CKind = OMPC_private;
1328
27.8k
    return DVar;
1329
27.8k
  }
1330
1331
40.6M
  DVar.DKind = Iter->Directive;
1332
  // Explicitly specified attributes and local variables with predetermined
1333
  // attributes.
1334
40.6M
  if (Iter->SharingMap.count(D)) {
1335
545k
    const DSAInfo &Data = Iter->SharingMap.lookup(D);
1336
545k
    DVar.RefExpr = Data.RefExpr.getPointer();
1337
545k
    DVar.PrivateCopy = Data.PrivateCopy;
1338
545k
    DVar.CKind = Data.Attributes;
1339
545k
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1340
545k
    DVar.Modifier = Data.Modifier;
1341
545k
    DVar.AppliedToPointee = Data.AppliedToPointee;
1342
545k
    return DVar;
1343
545k
  }
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
40.1M
  switch (Iter->DefaultAttr) {
1350
10.6k
  case DSA_shared:
1351
10.6k
    DVar.CKind = OMPC_shared;
1352
10.6k
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1353
10.6k
    return DVar;
1354
16.3k
  case DSA_none:
1355
16.3k
    return DVar;
1356
1.82k
  case DSA_firstprivate:
1357
1.82k
    if (VD && 
VD->getStorageDuration() == SD_Static1.62k
&&
1358
1.82k
        
VD->getDeclContext()->isFileContext()1.29k
) {
1359
1.14k
      DVar.CKind = OMPC_unknown;
1360
1.14k
    } else {
1361
680
      DVar.CKind = OMPC_firstprivate;
1362
680
    }
1363
1.82k
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1364
1.82k
    return DVar;
1365
1.43k
  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
1.43k
    if (VD && 
VD->getStorageDuration() == SD_Static1.27k
&&
1370
1.43k
        
VD->getDeclContext()->isFileContext()974
) {
1371
932
      DVar.CKind = OMPC_unknown;
1372
932
    } else {
1373
501
      DVar.CKind = OMPC_private;
1374
501
    }
1375
1.43k
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1376
1.43k
    return DVar;
1377
40.0M
  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
40.0M
    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1383
40.0M
    if ((isOpenMPParallelDirective(DVar.DKind) &&
1384
40.0M
         
!isOpenMPTaskLoopDirective(DVar.DKind)2.77M
) ||
1385
40.0M
        
isOpenMPTeamsDirective(DVar.DKind)37.5M
) {
1386
4.01M
      DVar.CKind = OMPC_shared;
1387
4.01M
      return DVar;
1388
4.01M
    }
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
36.0M
    if (isOpenMPTaskingDirective(DVar.DKind)) {
1396
30.5M
      DSAVarData DVarTemp;
1397
30.5M
      const_iterator I = Iter, E = end();
1398
31.8M
      do {
1399
31.8M
        ++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
31.8M
        DVarTemp = getDSA(I, D);
1406
31.8M
        if (DVarTemp.CKind != OMPC_shared) {
1407
28.8M
          DVar.RefExpr = nullptr;
1408
28.8M
          DVar.CKind = OMPC_firstprivate;
1409
28.8M
          return DVar;
1410
28.8M
        }
1411
31.8M
      } while (
I != E2.98M
&&
!isImplicitTaskingRegion(I->Directive)1.63M
);
1412
1.64M
      DVar.CKind =
1413
1.64M
          (DVarTemp.CKind == OMPC_unknown) ? 
OMPC_firstprivate0
: OMPC_shared;
1414
1.64M
      return DVar;
1415
30.5M
    }
1416
40.1M
  }
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
5.57M
  return getDSA(++Iter, D);
1423
40.1M
}
1424
1425
const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1426
2.34k
                                         const Expr *NewDE) {
1427
2.34k
  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1428
2.34k
  D = getCanonicalDecl(D);
1429
2.34k
  SharingMapTy &StackElem = getTopOfStack();
1430
2.34k
  auto It = StackElem.AlignedMap.find(D);
1431
2.34k
  if (It == StackElem.AlignedMap.end()) {
1432
2.28k
    assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1433
2.28k
    StackElem.AlignedMap[D] = NewDE;
1434
2.28k
    return nullptr;
1435
2.28k
  }
1436
60
  assert(It->second && "Unexpected nullptr expr in the aligned map");
1437
60
  return It->second;
1438
60
}
1439
1440
const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1441
982
                                             const Expr *NewDE) {
1442
982
  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1443
982
  D = getCanonicalDecl(D);
1444
982
  SharingMapTy &StackElem = getTopOfStack();
1445
982
  auto It = StackElem.NontemporalMap.find(D);
1446
982
  if (It == StackElem.NontemporalMap.end()) {
1447
936
    assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1448
936
    StackElem.NontemporalMap[D] = NewDE;
1449
936
    return nullptr;
1450
936
  }
1451
46
  assert(It->second && "Unexpected nullptr expr in the aligned map");
1452
46
  return It->second;
1453
46
}
1454
1455
261k
void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1456
261k
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1457
261k
  D = getCanonicalDecl(D);
1458
261k
  SharingMapTy &StackElem = getTopOfStack();
1459
261k
  StackElem.LCVMap.try_emplace(
1460
261k
      D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1461
261k
}
1462
1463
const DSAStackTy::LCDeclInfo
1464
4.40M
DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1465
4.40M
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1466
4.40M
  D = getCanonicalDecl(D);
1467
4.40M
  const SharingMapTy &StackElem = getTopOfStack();
1468
4.40M
  auto It = StackElem.LCVMap.find(D);
1469
4.40M
  if (It != StackElem.LCVMap.end())
1470
6.30k
    return It->second;
1471
4.39M
  return {0, nullptr};
1472
4.40M
}
1473
1474
const DSAStackTy::LCDeclInfo
1475
208k
DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1476
208k
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1477
208k
  D = getCanonicalDecl(D);
1478
1.23M
  for (unsigned I = Level + 1; I > 0; 
--I1.02M
) {
1479
1.03M
    const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1480
1.03M
    auto It = StackElem.LCVMap.find(D);
1481
1.03M
    if (It != StackElem.LCVMap.end())
1482
4.78k
      return It->second;
1483
1.03M
  }
1484
203k
  return {0, nullptr};
1485
208k
}
1486
1487
const DSAStackTy::LCDeclInfo
1488
324
DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1489
324
  const SharingMapTy *Parent = getSecondOnStackOrNull();
1490
324
  assert(Parent && "Data-sharing attributes stack is empty");
1491
324
  D = getCanonicalDecl(D);
1492
324
  auto It = Parent->LCVMap.find(D);
1493
324
  if (It != Parent->LCVMap.end())
1494
317
    return It->second;
1495
7
  return {0, nullptr};
1496
324
}
1497
1498
154
const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1499
154
  const SharingMapTy *Parent = getSecondOnStackOrNull();
1500
154
  assert(Parent && "Data-sharing attributes stack is empty");
1501
154
  if (Parent->LCVMap.size() < I)
1502
14
    return nullptr;
1503
140
  for (const auto &Pair : Parent->LCVMap)
1504
210
    if (Pair.second.first == I)
1505
140
      return Pair.first;
1506
0
  return nullptr;
1507
140
}
1508
1509
void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1510
                        DeclRefExpr *PrivateCopy, unsigned Modifier,
1511
364k
                        bool AppliedToPointee) {
1512
364k
  D = getCanonicalDecl(D);
1513
364k
  if (A == OMPC_threadprivate) {
1514
4.29k
    DSAInfo &Data = Threadprivates[D];
1515
4.29k
    Data.Attributes = A;
1516
4.29k
    Data.RefExpr.setPointer(E);
1517
4.29k
    Data.PrivateCopy = nullptr;
1518
4.29k
    Data.Modifier = Modifier;
1519
360k
  } else {
1520
360k
    DSAInfo &Data = getTopOfStack().SharingMap[D];
1521
360k
    assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1522
360k
           (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1523
360k
           (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1524
360k
           (isLoopControlVariable(D).first && A == OMPC_private));
1525
360k
    Data.Modifier = Modifier;
1526
360k
    if (A == OMPC_lastprivate && 
Data.Attributes == OMPC_firstprivate12.5k
) {
1527
328
      Data.RefExpr.setInt(/*IntVal=*/true);
1528
328
      return;
1529
328
    }
1530
359k
    const bool IsLastprivate =
1531
359k
        A == OMPC_lastprivate || 
Data.Attributes == OMPC_lastprivate347k
;
1532
359k
    Data.Attributes = A;
1533
359k
    Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1534
359k
    Data.PrivateCopy = PrivateCopy;
1535
359k
    Data.AppliedToPointee = AppliedToPointee;
1536
359k
    if (PrivateCopy) {
1537
3.89k
      DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1538
3.89k
      Data.Modifier = Modifier;
1539
3.89k
      Data.Attributes = A;
1540
3.89k
      Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1541
3.89k
      Data.PrivateCopy = nullptr;
1542
3.89k
      Data.AppliedToPointee = AppliedToPointee;
1543
3.89k
    }
1544
359k
  }
1545
364k
}
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
1.39M
                             DeclRefExpr *OrigRef = nullptr) {
1551
1.39M
  DeclContext *DC = SemaRef.CurContext;
1552
1.39M
  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1553
1.39M
  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1554
1.39M
  auto *Decl =
1555
1.39M
      VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1556
1.39M
  if (Attrs) {
1557
1.98k
    for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1558
2.63k
         I != E; 
++I648
)
1559
648
      Decl->addAttr(*I);
1560
1.98k
  }
1561
1.39M
  Decl->setImplicit();
1562
1.39M
  if (OrigRef) {
1563
334k
    Decl->addAttr(
1564
334k
        OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1565
334k
  }
1566
1.39M
  return Decl;
1567
1.39M
}
1568
1569
static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1570
                                     SourceLocation Loc,
1571
2.63M
                                     bool RefersToCapture = false) {
1572
2.63M
  D->setReferenced();
1573
2.63M
  D->markUsed(S.Context);
1574
2.63M
  return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1575
2.63M
                             SourceLocation(), D, RefersToCapture, Loc, Ty,
1576
2.63M
                             VK_LValue);
1577
2.63M
}
1578
1579
void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1580
6.34k
                                           BinaryOperatorKind BOK) {
1581
6.34k
  D = getCanonicalDecl(D);
1582
6.34k
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1583
6.34k
  assert(
1584
6.34k
      getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1585
6.34k
      "Additional reduction info may be specified only for reduction items.");
1586
6.34k
  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1587
6.34k
  assert(ReductionData.ReductionRange.isInvalid() &&
1588
6.34k
         (getTopOfStack().Directive == OMPD_taskgroup ||
1589
6.34k
          ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1590
6.34k
            isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1591
6.34k
           !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1592
6.34k
         "Additional reduction info may be specified only once for reduction "
1593
6.34k
         "items.");
1594
6.34k
  ReductionData.set(BOK, SR);
1595
6.34k
  Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1596
6.34k
  if (!TaskgroupReductionRef) {
1597
6.09k
    VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1598
6.09k
                               SemaRef.Context.VoidPtrTy, ".task_red.");
1599
6.09k
    TaskgroupReductionRef =
1600
6.09k
        buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1601
6.09k
  }
1602
6.34k
}
1603
1604
void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1605
120
                                           const Expr *ReductionRef) {
1606
120
  D = getCanonicalDecl(D);
1607
120
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1608
120
  assert(
1609
120
      getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1610
120
      "Additional reduction info may be specified only for reduction items.");
1611
120
  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1612
120
  assert(ReductionData.ReductionRange.isInvalid() &&
1613
120
         (getTopOfStack().Directive == OMPD_taskgroup ||
1614
120
          ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1615
120
            isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1616
120
           !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1617
120
         "Additional reduction info may be specified only once for reduction "
1618
120
         "items.");
1619
120
  ReductionData.set(ReductionRef, SR);
1620
120
  Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1621
120
  if (!TaskgroupReductionRef) {
1622
120
    VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1623
120
                               SemaRef.Context.VoidPtrTy, ".task_red.");
1624
120
    TaskgroupReductionRef =
1625
120
        buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1626
120
  }
1627
120
}
1628
1629
const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1630
    const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1631
4.35k
    Expr *&TaskgroupDescriptor) const {
1632
4.35k
  D = getCanonicalDecl(D);
1633
4.35k
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1634
4.78k
  
for (const_iterator I = begin() + 1, E = end(); 4.35k
I != E;
++I428
) {
1635
4.05k
    const DSAInfo &Data = I->SharingMap.lookup(D);
1636
4.05k
    if (Data.Attributes != OMPC_reduction ||
1637
4.05k
        
Data.Modifier != OMPC_REDUCTION_task3.62k
)
1638
428
      continue;
1639
3.62k
    const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1640
3.62k
    if (!ReductionData.ReductionOp ||
1641
3.62k
        ReductionData.ReductionOp.is<const Expr *>())
1642
120
      return DSAVarData();
1643
3.50k
    SR = ReductionData.ReductionRange;
1644
3.50k
    BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1645
3.50k
    assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1646
3.50k
                                       "expression for the descriptor is not "
1647
3.50k
                                       "set.");
1648
3.50k
    TaskgroupDescriptor = I->TaskgroupReductionRef;
1649
3.50k
    return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1650
3.50k
                      Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1651
3.50k
                      /*AppliedToPointee=*/false);
1652
3.50k
  }
1653
728
  return DSAVarData();
1654
4.35k
}
1655
1656
const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1657
    const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1658
4.35k
    Expr *&TaskgroupDescriptor) const {
1659
4.35k
  D = getCanonicalDecl(D);
1660
4.35k
  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1661
4.78k
  
for (const_iterator I = begin() + 1, E = end(); 4.35k
I != E;
++I428
) {
1662
4.05k
    const DSAInfo &Data = I->SharingMap.lookup(D);
1663
4.05k
    if (Data.Attributes != OMPC_reduction ||
1664
4.05k
        
Data.Modifier != OMPC_REDUCTION_task3.62k
)
1665
428
      continue;
1666
3.62k
    const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1667
3.62k
    if (!ReductionData.ReductionOp ||
1668
3.62k
        !ReductionData.ReductionOp.is<const Expr *>())
1669
3.50k
      return DSAVarData();
1670
120
    SR = ReductionData.ReductionRange;
1671
120
    ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1672
120
    assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1673
120
                                       "expression for the descriptor is not "
1674
120
                                       "set.");
1675
120
    TaskgroupDescriptor = I->TaskgroupReductionRef;
1676
120
    return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1677
120
                      Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1678
120
                      /*AppliedToPointee=*/false);
1679
120
  }
1680
728
  return DSAVarData();
1681
4.35k
}
1682
1683
40.6M
bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1684
40.6M
  D = D->getCanonicalDecl();
1685
55.1M
  for (const_iterator E = end(); I != E; 
++I14.4M
) {
1686
51.5M
    if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1687
51.5M
        
isOpenMPTargetExecutionDirective(I->Directive)16.1M
) {
1688
37.0M
      if (I->CurScope) {
1689
35.0M
        Scope *TopScope = I->CurScope->getParent();
1690
35.0M
        Scope *CurScope = getCurScope();
1691
794M
        while (CurScope && CurScope != TopScope && 
!CurScope->isDeclScope(D)759M
)
1692
759M
          CurScope = CurScope->getParent();
1693
35.0M
        return CurScope != TopScope;
1694
35.0M
      }
1695
5.77M
      
for (DeclContext *DC = D->getDeclContext(); 1.91M
DC;
DC = DC->getParent()3.86M
)
1696
3.87M
        if (I->Context == DC)
1697
14.1k
          return true;
1698
1.90M
      return false;
1699
1.91M
    }
1700
51.5M
  }
1701
3.66M
  return false;
1702
40.6M
}
1703
1704
static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1705
                                  bool AcceptIfMutable = true,
1706
158k
                                  bool *IsClassType = nullptr) {
1707
158k
  ASTContext &Context = SemaRef.getASTContext();
1708
158k
  Type = Type.getNonReferenceType().getCanonicalType();
1709
158k
  bool IsConstant = Type.isConstant(Context);
1710
158k
  Type = Context.getBaseElementType(Type);
1711
158k
  const CXXRecordDecl *RD = AcceptIfMutable && 
SemaRef.getLangOpts().CPlusPlus37.8k
1712
158k
                                ? 
Type->getAsCXXRecordDecl()35.5k
1713
158k
                                : 
nullptr122k
;
1714
158k
  if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1715
2.34k
    if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1716
2.34k
      RD = CTD->getTemplatedDecl();
1717
158k
  if (IsClassType)
1718
157k
    *IsClassType = RD;
1719
158k
  return IsConstant && 
!(24.4k
SemaRef.getLangOpts().CPlusPlus24.4k
&&
RD24.4k
&&
1720
24.4k
                         
RD->hasDefinition()1.20k
&&
RD->hasMutableFields()1.20k
);
1721
158k
}
1722
1723
static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1724
                                      QualType Type, OpenMPClauseKind CKind,
1725
                                      SourceLocation ELoc,
1726
                                      bool AcceptIfMutable = true,
1727
157k
                                      bool ListItemNotVar = false) {
1728
157k
  ASTContext &Context = SemaRef.getASTContext();
1729
157k
  bool IsClassType;
1730
157k
  if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1731
23.5k
    unsigned Diag = ListItemNotVar ? 
diag::err_omp_const_list_item0
1732
23.5k
                    : IsClassType  ? 
diag::err_omp_const_not_mutable_variable316
1733
23.5k
                                   : 
diag::err_omp_const_variable23.1k
;
1734
23.5k
    SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1735
23.5k
    if (!ListItemNotVar && D) {
1736
23.5k
      const VarDecl *VD = dyn_cast<VarDecl>(D);
1737
23.5k
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1738
23.5k
                               VarDecl::DeclarationOnly;
1739
23.5k
      SemaRef.Diag(D->getLocation(),
1740
23.5k
                   IsDecl ? 
diag::note_previous_decl6.44k
:
diag::note_defined_here17.0k
)
1741
23.5k
          << D;
1742
23.5k
    }
1743
23.5k
    return true;
1744
23.5k
  }
1745
134k
  return false;
1746
157k
}
1747
1748
const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1749
5.22M
                                                   bool FromParent) {
1750
5.22M
  D = getCanonicalDecl(D);
1751
5.22M
  DSAVarData DVar;
1752
1753
5.22M
  auto *VD = dyn_cast<VarDecl>(D);
1754
5.22M
  auto TI = Threadprivates.find(D);
1755
5.22M
  if (TI != Threadprivates.end()) {
1756
47.8k
    DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1757
47.8k
    DVar.CKind = OMPC_threadprivate;
1758
47.8k
    DVar.Modifier = TI->getSecond().Modifier;
1759
47.8k
    return DVar;
1760
47.8k
  }
1761
5.17M
  if (VD && 
VD->hasAttr<OMPThreadPrivateDeclAttr>()5.13M
) {
1762
12
    DVar.RefExpr = buildDeclRefExpr(
1763
12
        SemaRef, VD, D->getType().getNonReferenceType(),
1764
12
        VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1765
12
    DVar.CKind = OMPC_threadprivate;
1766
12
    addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1767
12
    return DVar;
1768
12
  }
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
5.17M
  if ((VD && 
VD->getTLSKind() != VarDecl::TLS_None5.13M
&&
1773
5.17M
       
!(15
VD->hasAttr<OMPThreadPrivateDeclAttr>()15
&&
1774
15
         
SemaRef.getLangOpts().OpenMPUseTLS0
&&
1775
15
         
SemaRef.getASTContext().getTargetInfo().isTLSSupported()0
)) ||
1776
5.17M
      
(5.17M
VD5.17M
&&
VD->getStorageClass() == SC_Register5.13M
&&
1777
5.17M
       
VD->hasAttr<AsmLabelAttr>()376
&&
!VD->isLocalVarDecl()0
)) {
1778
15
    DVar.RefExpr = buildDeclRefExpr(
1779
15
        SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1780
15
    DVar.CKind = OMPC_threadprivate;
1781
15
    addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1782
15
    return DVar;
1783
15
  }
1784
5.17M
  if (SemaRef.getLangOpts().OpenMPCUDAMode && 
VD12.2k
&&
1785
5.17M
      
VD->isLocalVarDeclOrParm()12.2k
&&
!isStackEmpty()12.1k
&&
1786
5.17M
      
!isLoopControlVariable(D).first12.1k
) {
1787
11.9k
    const_iterator IterTarget =
1788
12.1k
        std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1789
12.1k
          return isOpenMPTargetExecutionDirective(Data.Directive);
1790
12.1k
        });
1791
11.9k
    if (IterTarget != end()) {
1792
11.8k
      const_iterator ParentIterTarget = IterTarget + 1;
1793
24.0k
      for (const_iterator Iter = begin(); Iter != ParentIterTarget; 
++Iter12.1k
) {
1794
12.1k
        if (isOpenMPLocal(VD, Iter)) {
1795
13
          DVar.RefExpr =
1796
13
              buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1797
13
                               D->getLocation());
1798
13
          DVar.CKind = OMPC_threadprivate;
1799
13
          return DVar;
1800
13
        }
1801
12.1k
      }
1802
11.8k
      if (!isClauseParsingMode() || 
IterTarget != begin()494
) {
1803
11.4k
        auto DSAIter = IterTarget->SharingMap.find(D);
1804
11.4k
        if (DSAIter != IterTarget->SharingMap.end() &&
1805
11.4k
            
isOpenMPPrivate(DSAIter->getSecond().Attributes)1.64k
) {
1806
1.64k
          DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1807
1.64k
          DVar.CKind = OMPC_threadprivate;
1808
1.64k
          return DVar;
1809
1.64k
        }
1810
9.82k
        const_iterator End = end();
1811
9.82k
        if (!SemaRef.isOpenMPCapturedByRef(D,
1812
9.82k
                                           std::distance(ParentIterTarget, End),
1813
9.82k
                                           /*OpenMPCaptureLevel=*/0)) {
1814
2.80k
          DVar.RefExpr =
1815
2.80k
              buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1816
2.80k
                               IterTarget->ConstructLoc);
1817
2.80k
          DVar.CKind = OMPC_threadprivate;
1818
2.80k
          return DVar;
1819
2.80k
        }
1820
9.82k
      }
1821
11.8k
    }
1822
11.9k
  }
1823
1824
5.16M
  if (isStackEmpty())
1825
    // Not in OpenMP execution region and top scope was already checked.
1826
1.69k
    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
5.16M
  if (VD && 
VD->isStaticDataMember()5.13M
) {
1836
    // Check for explicitly specified attributes.
1837
33.3k
    const_iterator I = begin();
1838
33.3k
    const_iterator EndI = end();
1839
33.3k
    if (FromParent && 
I != EndI10.2k
)
1840
10.2k
      ++I;
1841
33.3k
    if (I != EndI) {
1842
33.3k
      auto It = I->SharingMap.find(D);
1843
33.3k
      if (It != I->SharingMap.end()) {
1844
3.21k
        const DSAInfo &Data = It->getSecond();
1845
3.21k
        DVar.RefExpr = Data.RefExpr.getPointer();
1846
3.21k
        DVar.PrivateCopy = Data.PrivateCopy;
1847
3.21k
        DVar.CKind = Data.Attributes;
1848
3.21k
        DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1849
3.21k
        DVar.DKind = I->Directive;
1850
3.21k
        DVar.Modifier = Data.Modifier;
1851
3.21k
        DVar.AppliedToPointee = Data.AppliedToPointee;
1852
3.21k
        return DVar;
1853
3.21k
      }
1854
33.3k
    }
1855
1856
30.1k
    DVar.CKind = OMPC_shared;
1857
30.1k
    return DVar;
1858
33.3k
  }
1859
1860
5.13M
  auto &&MatchesAlways = [](OpenMPDirectiveKind) 
{ return true; }16
;
1861
  // The predetermined shared attribute for const-qualified types having no
1862
  // mutable members was removed after OpenMP 3.1.
1863
5.13M
  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
64
    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
16
      DSAVarData DVarTemp = hasInnermostDSA(
1872
16
          D,
1873
16
          [](OpenMPClauseKind C, bool) {
1874
16
            return C == OMPC_firstprivate || C == OMPC_shared;
1875
16
          },
1876
16
          MatchesAlways, FromParent);
1877
16
      if (DVarTemp.CKind != OMPC_unknown && 
DVarTemp.RefExpr0
)
1878
0
        return DVarTemp;
1879
1880
16
      DVar.CKind = OMPC_shared;
1881
16
      return DVar;
1882
16
    }
1883
64
  }
1884
1885
  // Explicitly specified attributes and local variables with predetermined
1886
  // attributes.
1887
5.13M
  const_iterator I = begin();
1888
5.13M
  const_iterator EndI = end();
1889
5.13M
  if (FromParent && 
I != EndI221k
)
1890
221k
    ++I;
1891
5.13M
  if (I == EndI)
1892
6
    return DVar;
1893
5.13M
  auto It = I->SharingMap.find(D);
1894
5.13M
  if (It != I->SharingMap.end()) {
1895
674k
    const DSAInfo &Data = It->getSecond();
1896
674k
    DVar.RefExpr = Data.RefExpr.getPointer();
1897
674k
    DVar.PrivateCopy = Data.PrivateCopy;
1898
674k
    DVar.CKind = Data.Attributes;
1899
674k
    DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1900
674k
    DVar.DKind = I->Directive;
1901
674k
    DVar.Modifier = Data.Modifier;
1902
674k
    DVar.AppliedToPointee = Data.AppliedToPointee;
1903
674k
  }
1904
1905
5.13M
  return DVar;
1906
5.13M
}
1907
1908
const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1909
115k
                                                        bool FromParent) const {
1910
115k
  if (isStackEmpty()) {
1911
0
    const_iterator I;
1912
0
    return getDSA(I, D);
1913
0
  }
1914
115k
  D = getCanonicalDecl(D);
1915
115k
  const_iterator StartI = begin();
1916
115k
  const_iterator EndI = end();
1917
115k
  if (FromParent && 
StartI != EndI7.77k
)
1918
7.77k
    ++StartI;
1919
115k
  return getDSA(StartI, D);
1920
115k
}
1921
1922
const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1923
295k
                                                        unsigned Level) const {
1924
295k
  if (getStackSize() <= Level)
1925
0
    return DSAVarData();
1926
295k
  D = getCanonicalDecl(D);
1927
295k
  const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1928
295k
  return getDSA(StartI, D);
1929
295k
}
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
4.15M
                   bool FromParent) const {
1938
4.15M
  if (isStackEmpty())
1939
709
    return {};
1940
4.15M
  D = getCanonicalDecl(D);
1941
4.15M
  const_iterator I = begin();
1942
4.15M
  const_iterator EndI = end();
1943
4.15M
  if (FromParent && 
I != EndI1.05M
)
1944
1.05M
    ++I;
1945
12.7M
  for (; I != EndI; 
++I8.61M
) {
1946
8.62M
    if (!DPred(I->Directive) &&
1947
8.62M
        
!isImplicitOrExplicitTaskingRegion(I->Directive)0
)
1948
0
      continue;
1949
8.62M
    const_iterator NewI = I;
1950
8.62M
    DSAVarData DVar = getDSA(NewI, D);
1951
8.62M
    if (I == NewI && 
CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr)5.81M
)
1952
14.3k
      return DVar;
1953
8.62M
  }
1954
4.14M
  return {};
1955
4.15M
}
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
109k
    bool FromParent) const {
1961
109k
  if (isStackEmpty())
1962
0
    return {};
1963
109k
  D = getCanonicalDecl(D);
1964
109k
  const_iterator StartI = begin();
1965
109k
  const_iterator EndI = end();
1966
109k
  if (FromParent && 
StartI != EndI109k
)
1967
109k
    ++StartI;
1968
109k
  if (StartI == EndI || 
!DPred(StartI->Directive)61.1k
)
1969
83.3k
    return {};
1970
26.2k
  const_iterator NewI = StartI;
1971
26.2k
  DSAVarData DVar = getDSA(NewI, D);
1972
26.2k
  return (NewI == StartI && 
CPred(DVar.CKind, DVar.AppliedToPointee)25.9k
)
1973
26.2k
             ? 
DVar162
1974
26.2k
             : 
DSAVarData()26.1k
;
1975
109k
}
1976
1977
bool DSAStackTy::hasExplicitDSA(
1978
    const ValueDecl *D,
1979
    const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1980
5.81M
    unsigned Level, bool NotLastprivate) const {
1981
5.81M
  if (getStackSize() <= Level)
1982
0
    return false;
1983
5.81M
  D = getCanonicalDecl(D);
1984
5.81M
  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1985
5.81M
  auto I = StackElem.SharingMap.find(D);
1986
5.81M
  if (I != StackElem.SharingMap.end() && 
I->getSecond().RefExpr.getPointer()747k
&&
1987
5.81M
      
CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee)747k
&&
1988
5.81M
      
(242k
!NotLastprivate242k
||
!I->getSecond().RefExpr.getInt()17.0k
))
1989
241k
    return true;
1990
  // Check predetermined rules for the loop control variables.
1991
5.57M
  auto LI = StackElem.LCVMap.find(D);
1992
5.57M
  if (LI != StackElem.LCVMap.end())
1993
35.3k
    return CPred(OMPC_private, /*AppliedToPointee=*/false);
1994
5.53M
  return false;
1995
5.57M
}
1996
1997
bool DSAStackTy::hasExplicitDirective(
1998
    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1999
12.5M
    unsigned Level) const {
2000
12.5M
  if (getStackSize() <= Level)
2001
0
    return false;
2002
12.5M
  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
2003
12.5M
  return DPred(StackElem.Directive);
2004
12.5M
}
2005
2006
bool DSAStackTy::hasDirective(
2007
    const llvm::function_ref<bool(OpenMPDirectiveKind,
2008
                                  const DeclarationNameInfo &, SourceLocation)>
2009
        DPred,
2010
307k
    bool FromParent) const {
2011
  // We look only in the enclosing region.
2012
307k
  size_t Skip = FromParent ? 
20
: 1;
2013
307k
  for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
2014
476k
       I != E; 
++I169k
) {
2015
351k
    if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
2016
182k
      return true;
2017
351k
  }
2018
124k
  return false;
2019
307k
}
2020
2021
90.9k
void Sema::InitDataSharingAttributesStack() {
2022
90.9k
  VarDataSharingAttributesStack = new DSAStackTy(*this);
2023
90.9k
}
2024
2025
111M
#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2026
2027
116k
void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
2028
2029
965k
void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
2030
965k
  DSAStack->popFunction(OldFSI);
2031
965k
}
2032
2033
250
static bool isOpenMPDeviceDelayedContext(Sema &S) {
2034
250
  assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsTargetDevice &&
2035
250
         "Expected OpenMP device compilation.");
2036
250
  return !S.isInOpenMPTargetExecutionDirective();
2037
250
}
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
381
                             const FunctionDecl *FD) {
2051
381
  assert(LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice &&
2052
381
         "Expected OpenMP device compilation.");
2053
2054
381
  SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2055
381
  if (FD) {
2056
360
    FunctionEmissionStatus FES = getEmissionStatus(FD);
2057
360
    switch (FES) {
2058
81
    case FunctionEmissionStatus::Emitted:
2059
81
      Kind = SemaDiagnosticBuilder::K_Immediate;
2060
81
      break;
2061
250
    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
250
      Kind = isOpenMPDeviceDelayedContext(*this)
2070
250
                 ? 
SemaDiagnosticBuilder::K_Deferred213
2071
250
                 : 
SemaDiagnosticBuilder::K_Immediate37
;
2072
250
      break;
2073
29
    case FunctionEmissionStatus::TemplateDiscarded:
2074
29
    case FunctionEmissionStatus::OMPDiscarded:
2075
29
      Kind = SemaDiagnosticBuilder::K_Nop;
2076
29
      break;
2077
0
    case FunctionEmissionStatus::CUDADiscarded:
2078
0
      llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
2079
0
      break;
2080
360
    }
2081
360
  }
2082
2083
381
  return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2084
381
}
2085
2086
Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
2087
                                                       unsigned DiagID,
2088
7
                                                       const FunctionDecl *FD) {
2089
7
  assert(LangOpts.OpenMP && !LangOpts.OpenMPIsTargetDevice &&
2090
7
         "Expected OpenMP host compilation.");
2091
2092
7
  SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2093
7
  if (FD) {
2094
6
    FunctionEmissionStatus FES = getEmissionStatus(FD);
2095
6
    switch (FES) {
2096
0
    case FunctionEmissionStatus::Emitted:
2097
0
      Kind = SemaDiagnosticBuilder::K_Immediate;
2098
0
      break;
2099
6
    case FunctionEmissionStatus::Unknown:
2100
6
      Kind = SemaDiagnosticBuilder::K_Deferred;
2101
6
      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
6
    }
2108
6
  }
2109
2110
7
  return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2111
7
}
2112
2113
static OpenMPDefaultmapClauseKind
2114
1.11M
getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
2115
1.11M
  if (LO.OpenMP <= 45) {
2116
315k
    if (VD->getType().getNonReferenceType()->isScalarType())
2117
279k
      return OMPC_DEFAULTMAP_scalar;
2118
35.8k
    return OMPC_DEFAULTMAP_aggregate;
2119
315k
  }
2120
796k
  if (VD->getType().getNonReferenceType()->isAnyPointerType())
2121
158k
    return OMPC_DEFAULTMAP_pointer;
2122
637k
  if (VD->getType().getNonReferenceType()->isScalarType())
2123
573k
    return OMPC_DEFAULTMAP_scalar;
2124
64.6k
  return OMPC_DEFAULTMAP_aggregate;
2125
637k
}
2126
2127
bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
2128
1.68M
                                 unsigned OpenMPCaptureLevel) const {
2129
1.68M
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2130
2131
1.68M
  ASTContext &Ctx = getASTContext();
2132
1.68M
  bool IsByRef = true;
2133
2134
  // Find the directive that is associated with the provided scope.
2135
1.68M
  D = cast<ValueDecl>(D->getCanonicalDecl());
2136
1.68M
  QualType Ty = D->getType();
2137
2138
1.68M
  bool IsVariableUsedInMapClause = false;
2139
1.68M
  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
1.06M
    if (Ty->isReferenceType())
2195
42.5k
      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
1.06M
    bool IsVariableAssociatedWithSection = false;
2201
2202
1.06M
    DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2203
1.06M
        D, Level,
2204
1.06M
        [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2205
1.06M
         D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2206
1.06M
                MapExprComponents,
2207
1.06M
            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
31.7k
          if (WhereFoundClauseKind != OMPC_map &&
2212
31.7k
              
WhereFoundClauseKind != OMPC_has_device_addr2.43k
)
2213
2.17k
            return false;
2214
2215
29.5k
          auto EI = MapExprComponents.rbegin();
2216
29.5k
          auto EE = MapExprComponents.rend();
2217
2218
29.5k
          assert(EI != EE && "Invalid map expression!");
2219
2220
29.5k
          if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2221
29.4k
            IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2222
2223
29.5k
          ++EI;
2224
29.5k
          if (EI == EE)
2225
19.3k
            return false;
2226
10.1k
          auto Last = std::prev(EE);
2227
10.1k
          const auto *UO =
2228
10.1k
              dyn_cast<UnaryOperator>(Last->getAssociatedExpression());
2229
10.1k
          if ((UO && 
UO->getOpcode() == UO_Deref24
) ||
2230
10.1k
              
isa<ArraySubscriptExpr>(Last->getAssociatedExpression())10.1k
||
2231
10.1k
              
isa<OMPArraySectionExpr>(Last->getAssociatedExpression())9.39k
||
2232
10.1k
              
isa<MemberExpr>(EI->getAssociatedExpression())2.15k
||
2233
10.1k
              
isa<OMPArrayShapingExpr>(Last->getAssociatedExpression())96
) {
2234
10.1k
            IsVariableAssociatedWithSection = true;
2235
            // There is nothing more we need to know about this variable.
2236
10.1k
            return true;
2237
10.1k
          }
2238
2239
          // Keep looking for more map info.
2240
0
          return false;
2241
10.1k
        });
2242
2243
1.06M
    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
29.3k
      IsByRef = !(Ty->isPointerType() && 
IsVariableAssociatedWithSection4.53k
);
2247
1.03M
    } 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
1.03M
      IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2252
1.03M
                 
!Ty->isAnyPointerType()8
) ||
2253
1.03M
                
!Ty->isScalarType()1.03M
||
2254
1.03M
                
DSAStack702k
->isDefaultmapCapturedByRef(
2255
702k
                    Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2256
1.03M
                
DSAStack696k
->hasExplicitDSA(
2257
696k
                    D,
2258
696k
                    [](OpenMPClauseKind K, bool AppliedToPointee) {
2259
46.6k
                      return K == OMPC_reduction && 
!AppliedToPointee20.6k
;
2260
46.6k
                    },
2261
696k
                    Level);
2262
1.03M
    }
2263
1.06M
  }
2264
2265
1.68M
  if (IsByRef && 
Ty.getNonReferenceType()->isScalarType()1.00M
) {
2266
438k
    IsByRef =
2267
438k
        ((IsVariableUsedInMapClause &&
2268
438k
          
DSAStack13.0k
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2269
13.0k
              OMPD_target) ||
2270
438k
         
!(433k
DSAStack433k
->hasExplicitDSA(
2271
433k
               D,
2272
433k
               [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2273
96.2k
                 return K == OMPC_firstprivate ||
2274
96.2k
                        
(88.9k
K == OMPC_reduction88.9k
&&
AppliedToPointee61.8k
);
2275
96.2k
               },
2276
433k
               Level, /*NotLastprivate=*/true) ||
2277
433k
           
DSAStack426k
->isUsesAllocatorsDecl(Level, D)426k
)) &&
2278
        // If the variable is artificial and must be captured by value - try to
2279
        // capture by value.
2280
438k
        
!(431k
isa<OMPCapturedExprDecl>(D)431k
&&
!D->hasAttr<OMPCaptureNoInitAttr>()4.20k
&&
2281
431k
          
!cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()4.05k
) &&
2282
        // If the variable is implicitly firstprivate and scalar - capture by
2283
        // copy
2284
438k
        
!(428k
(428k
DSAStack428k
->getDefaultDSA() == DSA_firstprivate428k
||
2285
428k
           
DSAStack427k
->getDefaultDSA() == DSA_private427k
) &&
2286
428k
          
!563
DSAStack563
->hasExplicitDSA(
2287
563
              D, [](OpenMPClauseKind K, bool) 
{ return K != OMPC_unknown; }0
,
2288
563
              Level) &&
2289
428k
          
!563
DSAStack563
->isLoopControlVariable(D, Level).first);
2290
438k
  }
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
1.68M
  if (!IsByRef && 
(690k
Ctx.getTypeSizeInChars(Ty) >
2297
690k
                       Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2298
690k
                   Ctx.getAlignOfGlobalVarInChars(Ty) >
2299
688k
                       Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2300
1.71k
    IsByRef = true;
2301
1.71k
  }
2302
2303
1.68M
  return IsByRef;
2304
1.68M
}
2305
2306
847k
unsigned Sema::getOpenMPNestingLevel() const {
2307
847k
  assert(getLangOpts().OpenMP);
2308
847k
  return DSAStack->getNestingLevel();
2309
847k
}
2310
2311
36.1k
bool Sema::isInOpenMPTaskUntiedContext() const {
2312
36.1k
  return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2313
36.1k
         
DSAStack50
->isUntiedRegion()50
;
2314
36.1k
}
2315
2316
431k
bool Sema::isInOpenMPTargetExecutionDirective() const {
2317
431k
  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2318
431k
          
!137k
DSAStack137k
->isClauseParsingMode()) ||
2319
431k
         
DSAStack295k
->hasDirective(
2320
295k
             [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2321
330k
                SourceLocation) -> bool {
2322
330k
               return isOpenMPTargetExecutionDirective(K);
2323
330k
             },
2324
295k
             false);
2325
431k
}
2326
2327
818
bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
2328
  // Only rebuild for Field.
2329
818
  if (!dyn_cast<FieldDecl>(D))
2330
82
    return false;
2331
736
  DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2332
736
      D,
2333
736
      [](OpenMPClauseKind C, bool AppliedToPointee,
2334
736
         DefaultDataSharingAttributes DefaultAttr) {
2335
8
        return isOpenMPPrivate(C) && !AppliedToPointee &&
2336
8
               (DefaultAttr == DSA_firstprivate || 
DefaultAttr == DSA_private4
);
2337
8
      },
2338
736
      [](OpenMPDirectiveKind) 
{ return true; }13
,
2339
736
      DSAStack->isClauseParsingMode());
2340
736
  if (DVarPrivate.CKind != OMPC_unknown)
2341
8
    return true;
2342
728
  return false;
2343
736
}
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
2.20M
                                    unsigned StopAt) {
2352
2.20M
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2353
2.20M
  D = getCanonicalDecl(D);
2354
2355
2.20M
  auto *VD = dyn_cast<VarDecl>(D);
2356
  // Do not capture constexpr variables.
2357
2.20M
  if (VD && 
VD->isConstexpr()2.17M
)
2358
165
    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
2.20M
  DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2365
2.20M
      *DSAStack, CheckScopeInfo && 
DSAStack332k
->isBodyComplete()332k
);
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
2.20M
  if (VD && 
!VD->hasLocalStorage()2.17M
&&
2371
2.20M
      
(455k
getCurCapturedRegion()455k
||
getCurBlock()126k
||
getCurLambda()125k
)) {
2372
335k
    if (isInOpenMPTargetExecutionDirective()) {
2373
249k
      DSAStackTy::DSAVarData DVarTop =
2374
249k
          DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2375
249k
      if (DVarTop.CKind != OMPC_unknown && 
DVarTop.RefExpr103k
)
2376
92.6k
        return VD;
2377
      // If the declaration is enclosed in a 'declare target' directive,
2378
      // then it should not be captured.
2379
      //
2380
156k
      if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2381
318
        return nullptr;
2382
156k
      CapturedRegionScopeInfo *CSI = nullptr;
2383
156k
      for (FunctionScopeInfo *FSI : llvm::drop_begin(
2384
156k
               llvm::reverse(FunctionScopes),
2385
156k
               
CheckScopeInfo156k
?
(FunctionScopes.size() - (StopAt + 1))82.4k
:
073.7k
)) {
2386
156k
        if (!isa<CapturingScopeInfo>(FSI))
2387
36
          return nullptr;
2388
156k
        if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2389
156k
          if (RSI->CapRegionKind == CR_OpenMP) {
2390
156k
            CSI = RSI;
2391
156k
            break;
2392
156k
          }
2393
156k
      }
2394
156k
      assert(CSI && "Failed to find CapturedRegionScopeInfo");
2395
156k
      SmallVector<OpenMPDirectiveKind, 4> Regions;
2396
156k
      getOpenMPCaptureRegions(Regions,
2397
156k
                              DSAStack->getDirective(CSI->OpenMPLevel));
2398
156k
      if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2399
131k
        return VD;
2400
156k
    }
2401
111k
    if (isInOpenMPDeclareTargetContext()) {
2402
      // Try to mark variable as declare target if it is used in capturing
2403
      // regions.
2404
154
      if (LangOpts.OpenMP <= 45 &&
2405
154
          
!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)30
)
2406
8
        checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2407
154
      return nullptr;
2408
154
    }
2409
111k
  }
2410
2411
1.98M
  if (CheckScopeInfo) {
2412
215k
    bool OpenMPFound = false;
2413
219k
    for (unsigned I = StopAt + 1; I > 0; 
--I4.10k
) {
2414
219k
      FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2415
219k
      if (!isa<CapturingScopeInfo>(FSI))
2416
122k
        return nullptr;
2417
97.1k
      if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2418
93.1k
        if (RSI->CapRegionKind == CR_OpenMP) {
2419
93.0k
          OpenMPFound = true;
2420
93.0k
          break;
2421
93.0k
        }
2422
97.1k
    }
2423
93.2k
    if (!OpenMPFound)
2424
211
      return nullptr;
2425
93.2k
  }
2426
2427
1.85M
  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2428
1.85M
      
(1.83M
!1.83M
DSAStack1.83M
->isClauseParsingMode() ||
2429
1.83M
       
DSAStack462k
->getParentDirective() != OMPD_unknown462k
)) {
2430
1.80M
    auto &&Info = DSAStack->isLoopControlVariable(D);
2431
1.80M
    if (Info.first ||
2432
1.80M
        
(1.80M
VD1.80M
&&
VD->hasLocalStorage()1.78M
&&
2433
1.80M
         
isImplicitOrExplicitTaskingRegion(1.67M
DSAStack1.67M
->getCurrentDirective())) ||
2434
1.80M
        
(481k
VD481k
&&
DSAStack467k
->isForceVarCapturing()467k
))
2435
1.32M
      return VD ? 
VD1.32M
:
Info.second772
;
2436
480k
    DSAStackTy::DSAVarData DVarTop =
2437
480k
        DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2438
480k
    if (DVarTop.CKind != OMPC_unknown && 
isOpenMPPrivate(DVarTop.CKind)82.2k
&&
2439
480k
        
(73.9k
!VD73.9k
||
VD->hasLocalStorage()66.9k
||
!DVarTop.AppliedToPointee42.3k
))
2440
73.7k
      return VD ? 
VD66.8k
:
cast<VarDecl>(DVarTop.PrivateCopy->getDecl())6.96k
;
2441
    // Threadprivate variables must not be captured.
2442
407k
    if (isOpenMPThreadPrivate(DVarTop.CKind))
2443
3.97k
      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
403k
    DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2447
403k
        D,
2448
403k
        [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
2449
231k
          return isOpenMPPrivate(C) && 
!AppliedToPointee6.83k
;
2450
231k
        },
2451
828k
        [](OpenMPDirectiveKind) { return true; },
2452
403k
        DSAStack->isClauseParsingMode());
2453
    // Global shared must not be captured.
2454
403k
    if (VD && 
!VD->hasLocalStorage()395k
&&
DVarPrivate.CKind == OMPC_unknown60.0k
&&
2455
403k
        
(59.7k
(59.7k
DSAStack59.7k
->getDefaultDSA() != DSA_none59.7k
&&
2456
59.7k
          
DSAStack59.0k
->getDefaultDSA() != DSA_private59.0k
&&
2457
59.7k
          
DSAStack58.9k
->getDefaultDSA() != DSA_firstprivate58.9k
) ||
2458
59.7k
         
DVarTop.CKind == OMPC_shared942
))
2459
58.9k
      return nullptr;
2460
344k
    auto *FD = dyn_cast<FieldDecl>(D);
2461
344k
    if (DVarPrivate.CKind != OMPC_unknown && 
!VD6.70k
&&
FD1.53k
&&
2462
344k
        
!DVarPrivate.PrivateCopy1.53k
) {
2463
110
      DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2464
110
          D,
2465
110
          [](OpenMPClauseKind C, bool AppliedToPointee,
2466
110
             DefaultDataSharingAttributes DefaultAttr) {
2467
110
            return isOpenMPPrivate(C) && !AppliedToPointee &&
2468
110
                   (DefaultAttr == DSA_firstprivate ||
2469
110
                    
DefaultAttr == DSA_private44
);
2470
110
          },
2471
110
          [](OpenMPDirectiveKind) { return true; },
2472
110
          DSAStack->isClauseParsingMode());
2473
110
      if (DVarPrivate.CKind == OMPC_unknown)
2474
0
        return nullptr;
2475
2476
110
      VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD);
2477
110
      if (VD)
2478
90
        return VD;
2479
20
      if (getCurrentThisType().isNull())
2480
0
        return nullptr;
2481
20
      Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
2482
20
                                        /*IsImplicit=*/true);
2483
20
      const CXXScopeSpec CS = CXXScopeSpec();
2484
20
      Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(),
2485
20
                                 NestedNameSpecifierLoc(), SourceLocation(), FD,
2486
20
                                 DeclAccessPair::make(FD, FD->getAccess()),
2487
20
                                 /*HadMultipleCandidates=*/false,
2488
20
                                 DeclarationNameInfo(), FD->getType(),
2489
20
                                 VK_LValue, OK_Ordinary);
2490
20
      OMPCapturedExprDecl *CD = buildCaptureDecl(
2491
20
          *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2492
20
          CurContext->getParent(), /*AsExpression=*/false);
2493
20
      DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
2494
20
          *this, CD, CD->getType().getNonReferenceType(), SourceLocation());
2495
20
      VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
2496
20
      DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2497
20
      return VD;
2498
20
    }
2499
344k
    if (DVarPrivate.CKind != OMPC_unknown ||
2500
344k
        
(337k
VD337k
&&
(331k
DSAStack331k
->getDefaultDSA() == DSA_none331k
||
2501
331k
                
DSAStack331k
->getDefaultDSA() == DSA_private331k
||
2502
331k
                
DSAStack331k
->getDefaultDSA() == DSA_firstprivate331k
)))
2503
7.32k
      return VD ? 
VD5.90k
:
cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl())1.42k
;
2504
344k
  }
2505
392k
  return nullptr;
2506
1.85M
}
2507
2508
void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2509
39.2k
                                        unsigned Level) const {
2510
39.2k
  FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2511
39.2k
}
2512
2513
268k
void Sema::startOpenMPLoop() {
2514
268k
  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2515
268k
  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2516
265k
    DSAStack->loopInit();
2517
268k
}
2518
2519
166
void Sema::startOpenMPCXXRangeFor() {
2520
166
  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2521
166
  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2522
165
    DSAStack->resetPossibleLoopCounter();
2523
165
    DSAStack->loopStart();
2524
165
  }
2525
166
}
2526
2527
OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2528
3.73M
                                           unsigned CapLevel) const {
2529
3.73M
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2530
3.73M
  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2531
3.73M
      (!DSAStack->isClauseParsingMode() ||
2532
3.73M
       
DSAStack896k
->getParentDirective() != OMPD_unknown896k
)) {
2533
3.73M
    DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2534
3.73M
        D,
2535
3.73M
        [](OpenMPClauseKind C, bool AppliedToPointee,
2536
5.56M
           DefaultDataSharingAttributes DefaultAttr) {
2537
5.56M
          return isOpenMPPrivate(C) && 
!AppliedToPointee2.27M
&&
2538
5.56M
                 
DefaultAttr == DSA_private2.27M
;
2539
5.56M
        },
2540
7.78M
        [](OpenMPDirectiveKind) { return true; },
2541
3.73M
        DSAStack->isClauseParsingMode());
2542
3.73M
    if (DVarPrivate.CKind == OMPC_private && 
isa<OMPCapturedExprDecl>(D)369
&&
2543
3.73M
        
DSAStack83
->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D))83
&&
2544
3.73M
        
!44
DSAStack44
->isLoopControlVariable(D).first)
2545
44
      return OMPC_private;
2546
3.73M
  }
2547
3.73M
  if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2548
419k
    bool IsTriviallyCopyable =
2549
419k
        D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2550
419k
        !D->getType()
2551
340k
             .getNonReferenceType()
2552
340k
             .getCanonicalType()
2553
340k
             ->getAsCXXRecordDecl();
2554
419k
    OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2555
419k
    SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2556
419k
    getOpenMPCaptureRegions(CaptureRegions, DKind);
2557
419k
    if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2558
419k
        
(349k
IsTriviallyCopyable349k
||
2559
349k
         
!isOpenMPTaskLoopDirective(CaptureRegions[CapLevel])61.4k
)) {
2560
298k
      if (DSAStack->hasExplicitDSA(
2561
298k
              D,
2562
298k
              [](OpenMPClauseKind K, bool) 
{ return K == OMPC_firstprivate; }51.3k
,
2563
298k
              Level, /*NotLastprivate=*/true))
2564
9.10k
        return OMPC_firstprivate;
2565
289k
      DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2566
289k
      if (DVar.CKind != OMPC_shared &&
2567
289k
          
!207k
DSAStack207k
->isLoopControlVariable(D, Level).first &&
!DVar.RefExpr203k
) {
2568
171k
        DSAStack->addImplicitTaskFirstprivate(Level, D);
2569
171k
        return OMPC_firstprivate;
2570
171k
      }
2571
289k
    }
2572
419k
  }
2573
3.55M
  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()) &&
2574
3.55M
      
!isOpenMPLoopTransformationDirective(3.01M
DSAStack3.01M
->getCurrentDirective())) {
2575
3.01M
    if (DSAStack->getAssociatedLoops() > 0 && 
!1.53M
DSAStack1.53M
->isLoopStarted()) {
2576
54.6k
      DSAStack->resetPossibleLoopCounter(D);
2577
54.6k
      DSAStack->loopStart();
2578
54.6k
      return OMPC_private;
2579
54.6k
    }
2580
2.95M
    if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2581
2.95M
         
DSAStack2.44M
->isLoopControlVariable(D).first2.44M
) &&
2582
2.95M
        
!520k
DSAStack520k
->hasExplicitDSA(
2583
520k
            D, [](OpenMPClauseKind K, bool) 
{ return K != OMPC_private; }74.3k
,
2584
520k
            Level) &&
2585
2.95M
        
!isOpenMPSimdDirective(505k
DSAStack505k
->getCurrentDirective()))
2586
119k
      return OMPC_private;
2587
2.95M
  }
2588
3.37M
  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2589
3.37M
    if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2590
3.37M
        
DSAStack19.7k
->isForceVarCapturing()19.7k
&&
2591
3.37M
        
!466
DSAStack466
->hasExplicitDSA(
2592
466
            D, [](OpenMPClauseKind K, bool) 
{ return K == OMPC_copyin; }460
,
2593
466
            Level))
2594
6
      return OMPC_private;
2595
3.37M
  }
2596
  // User-defined allocators are private since they must be defined in the
2597
  // context of target region.
2598
3.37M
  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2599
3.37M
      
DSAStack2.07M
->isUsesAllocatorsDecl(Level, D).value_or(
2600
2.07M
          DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2601
2.07M
          DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2602
10
    return OMPC_private;
2603
3.37M
  return (DSAStack->hasExplicitDSA(
2604
3.37M
              D, [](OpenMPClauseKind K, bool) 
{ return K == OMPC_private; }373k
,
2605
3.37M
              Level) ||
2606
3.37M
          
(3.32M
DSAStack3.32M
->isClauseParsingMode()3.32M
&&
2607
3.32M
           
DSAStack822k
->getClauseParsingMode() == OMPC_private822k
) ||
2608
          // Consider taskgroup reduction descriptor variable a private
2609
          // to avoid possible capture in the region.
2610
3.37M
          
(3.30M
DSAStack3.30M
->hasExplicitDirective(
2611
3.30M
               [](OpenMPDirectiveKind K) {
2612
3.30M
                 return K == OMPD_taskgroup ||
2613
3.30M
                        
(3.26M
(3.26M
isOpenMPParallelDirective(K)3.26M
||
2614
3.26M
                          
isOpenMPWorksharingDirective(K)1.84M
) &&
2615
3.26M
                         
!isOpenMPSimdDirective(K)1.51M
);
2616
3.30M
               },
2617
3.30M
               Level) &&
2618
3.30M
           
DSAStack867k
->isTaskgroupReductionRef(D, Level)867k
))
2619
3.37M
             ? 
OMPC_private75.3k
2620
3.37M
             : 
OMPC_unknown3.30M
;
2621
3.37M
}
2622
2623
void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2624
486k
                                unsigned Level) {
2625
486k
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2626
486k
  D = getCanonicalDecl(D);
2627
486k
  OpenMPClauseKind OMPC = OMPC_unknown;
2628
602k
  for (unsigned I = 
DSAStack486k
->getNestingLevel() + 1; I > Level;
--I116k
) {
2629
486k
    const unsigned NewLevel = I - 1;
2630
486k
    if (DSAStack->hasExplicitDSA(
2631
486k
            D,
2632
486k
            [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2633
140k
              if (isOpenMPPrivate(K) && 
!AppliedToPointee138k
) {
2634
136k
                OMPC = K;
2635
136k
                return true;
2636
136k
              }
2637
3.82k
              return false;
2638
140k
            },
2639
486k
            NewLevel))
2640
136k
      break;
2641
349k
    if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2642
349k
            D, NewLevel,
2643
349k
            [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2644
349k
               OpenMPClauseKind) 
{ return true; }11.4k
)) {
2645
11.4k
      OMPC = OMPC_map;
2646
11.4k
      break;
2647
11.4k
    }
2648
338k
    if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2649
338k
                                       NewLevel)) {
2650
221k
      OMPC = OMPC_map;
2651
221k
      if (DSAStack->mustBeFirstprivateAtLevel(
2652
221k
              NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2653
171k
        OMPC = OMPC_firstprivate;
2654
221k
      break;
2655
221k
    }
2656
338k
  }
2657
486k
  if (OMPC != OMPC_unknown)
2658
369k
    FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2659
486k
}
2660
2661
bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2662
1.72M
                                      unsigned CaptureLevel) const {
2663
1.72M
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2664
  // Return true if the current level is no longer enclosed in a target region.
2665
2666
1.72M
  SmallVector<OpenMPDirectiveKind, 4> Regions;
2667
1.72M
  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2668
1.72M
  const auto *VD = dyn_cast<VarDecl>(D);
2669
1.72M
  return VD && !VD->hasLocalStorage() &&
2670
1.72M
         
DSAStack81.3k
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2671
81.3k
                                        Level) &&
2672
1.72M
         
Regions[CaptureLevel] != OMPD_task39.2k
;
2673
1.72M
}
2674
2675
bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2676
95.4k
                                      unsigned CaptureLevel) const {
2677
95.4k
  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2678
  // Return true if the current level is no longer enclosed in a target region.
2679
2680
95.4k
  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2681
95.4k
    if (!VD->hasLocalStorage()) {
2682
95.4k
      if (isInOpenMPTargetExecutionDirective())
2683
66.7k
        return true;
2684
28.6k
      DSAStackTy::DSAVarData TopDVar =
2685
28.6k
          DSAStack->getTopDSA(D, /*FromParent=*/false);
2686
28.6k
      unsigned NumLevels =
2687
28.6k
          getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2688
28.6k
      if (Level == 0)
2689
        // non-file scope static variale with default(firstprivate)
2690
        // should be gloabal captured.
2691
23.5k
        return (NumLevels == CaptureLevel + 1 &&
2692
23.5k
                
(17.7k
TopDVar.CKind != OMPC_shared17.7k
||
2693
17.7k
                 
DSAStack43
->getDefaultDSA() == DSA_firstprivate43
));
2694
6.19k
      
do 5.15k
{
2695
6.19k
        --Level;
2696
6.19k
        DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2697
6.19k
        if (DVar.CKind != OMPC_shared)
2698
1.12k
          return true;
2699
6.19k
      } while (
Level > 05.07k
);
2700
5.15k
    }
2701
95.4k
  }
2702
4.03k
  return true;
2703
95.4k
}
2704
2705
86.4k
void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2706
2707
void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2708
383
                                          OMPTraitInfo &TI) {
2709
383
  OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2710
383
}
2711
2712
377
void Sema::ActOnOpenMPEndDeclareVariant() {
2713
377
  assert(isInOpenMPDeclareVariantScope() &&
2714
377
         "Not in OpenMP declare variant scope!");
2715
2716
377
  OMPDeclareVariantScopes.pop_back();
2717
377
}
2718
2719
void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2720
                                         const FunctionDecl *Callee,
2721
15.6k
                                         SourceLocation Loc) {
2722
15.6k
  assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2723
15.6k
  std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2724
15.6k
      OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2725
  // Ignore host functions during device analyzis.
2726
15.6k
  if (LangOpts.OpenMPIsTargetDevice &&
2727
15.6k
      
(911
!DevTy911
||
*DevTy == OMPDeclareTargetDeclAttr::DT_Host722
))
2728
189
    return;
2729
  // Ignore nohost functions during host analyzis.
2730
15.4k
  if (!LangOpts.OpenMPIsTargetDevice && 
DevTy14.7k
&&
2731
15.4k
      
*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost256
)
2732
0
    return;
2733
15.4k
  const FunctionDecl *FD = Callee->getMostRecentDecl();
2734
15.4k
  DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2735
15.4k
  if (LangOpts.OpenMPIsTargetDevice && 
DevTy722
&&
2736
15.4k
      
*DevTy == OMPDeclareTargetDeclAttr::DT_Host321
) {
2737
    // Diagnose host function called during device codegen.
2738
4
    StringRef HostDevTy =
2739
4
        getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2740
4
    Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2741
4
    Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2742
4
         diag::note_omp_marked_device_type_here)
2743
4
        << HostDevTy;
2744
4
    return;
2745
4
  }
2746
15.4k
  if (!LangOpts.OpenMPIsTargetDevice && 
!LangOpts.OpenMPOffloadMandatory14.7k
&&
2747
15.4k
      
DevTy14.7k
&&
*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost293
) {
2748
    // In OpenMP 5.2 or later, if the function has a host variant then allow
2749
    // that to be called instead
2750
29
    auto &&HasHostAttr = [](const FunctionDecl *Callee) {
2751
3
      for (OMPDeclareVariantAttr *A :
2752
3
           Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2753
3
        auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2754
3
        auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2755
3
        std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2756
3
            OMPDeclareTargetDeclAttr::getDeviceType(
2757
3
                VariantFD->getMostRecentDecl());
2758
3
        if (!DevTy || 
*DevTy == OMPDeclareTargetDeclAttr::DT_Host2
)
2759
2
          return true;
2760
3
      }
2761
1
      return false;
2762
3
    };
2763
29
    if (getLangOpts().OpenMP >= 52 &&
2764
29
        
Callee->hasAttr<OMPDeclareVariantAttr>()4
&&
HasHostAttr(Callee)3
)
2765
2
      return;
2766
    // Diagnose nohost function called during host codegen.
2767
27
    StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2768
27
        OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2769
27
    Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2770
27
    Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2771
27
         diag::note_omp_marked_device_type_here)
2772
27
        << NoHostDevTy;
2773
27
  }
2774
15.4k
}
2775
2776
void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2777
                               const DeclarationNameInfo &DirName,
2778
543k
                               Scope *CurScope, SourceLocation Loc) {
2779
543k
  DSAStack->push(DKind, DirName, CurScope, Loc);
2780
543k
  PushExpressionEvaluationContext(
2781
543k
      ExpressionEvaluationContext::PotentiallyEvaluated);
2782
543k
}
2783
2784
386k
void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2785
386k
  DSAStack->setClauseParsingMode(K);
2786
386k
}
2787
2788
386k
void Sema::EndOpenMPClause() {
2789
386k
  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2790
386k
  CleanupVarDeclMarking();
2791
386k
}
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
461k
                                  ArrayRef<OMPClause *> Clauses) {
2801
461k
  bool InscanFound = false;
2802
461k
  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
461k
  for (OMPClause *C : Clauses) {
2808
321k
    if (C->getClauseKind() != OMPC_reduction)
2809
272k
      continue;
2810
48.8k
    auto *RC = cast<OMPReductionClause>(C);
2811
48.8k
    if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2812
193
      InscanFound = true;
2813
193
      InscanLoc = RC->getModifierLoc();
2814
193
      continue;
2815
193
    }
2816
48.7k
    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
902
      OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2823
902
      if (!(isOpenMPParallelDirective(CurDir) ||
2824
902
            
isOpenMPWorksharingDirective(CurDir)396
) ||
2825
902
          
isOpenMPSimdDirective(CurDir)592
)
2826
454
        S.Diag(RC->getModifierLoc(),
2827
454
               diag::err_omp_reduction_task_not_parallel_or_worksharing);
2828
902
      continue;
2829
902
    }
2830
48.7k
  }
2831
461k
  if (InscanFound) {
2832
235
    for (OMPClause *C : Clauses) {
2833
235
      if (C->getClauseKind() != OMPC_reduction)
2834
0
        continue;
2835
235
      auto *RC = cast<OMPReductionClause>(C);
2836
235
      if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2837
42
        S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2838
42
                   ? 
RC->getBeginLoc()21
2839
42
                   : 
RC->getModifierLoc()21
,
2840
42
               diag::err_omp_inscan_reduction_expected);
2841
42
        S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2842
42
        continue;
2843
42
      }
2844
313
      
for (Expr *Ref : RC->varlists())193
{
2845
313
        assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2846
313
        SourceLocation ELoc;
2847
313
        SourceRange ERange;
2848
313
        Expr *SimpleRefExpr = Ref;
2849
313
        auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2850
313
                                  /*AllowArraySection=*/true);
2851
313
        ValueDecl *D = Res.first;
2852
313
        if (!D)
2853
12
          continue;
2854
301
        if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2855
90
          S.Diag(Ref->getExprLoc(),
2856
90
                 diag::err_omp_reduction_not_inclusive_exclusive)
2857
90
              << Ref->getSourceRange();
2858
90
        }
2859
301
      }
2860
193
    }
2861
193
  }
2862
461k
}
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
543k
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
543k
  if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2881
461k
    for (OMPClause *C : D->clauses()) {
2882
321k
      if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2883
6.93k
        SmallVector<Expr *, 8> PrivateCopies;
2884
11.8k
        for (Expr *DE : Clause->varlists()) {
2885
11.8k
          if (DE->isValueDependent() || 
DE->isTypeDependent()9.49k
) {
2886
2.39k
            PrivateCopies.push_back(nullptr);
2887
2.39k
            continue;
2888
2.39k
          }
2889
9.49k
          auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2890
9.49k
          auto *VD = cast<VarDecl>(DRE->getDecl());
2891
9.49k
          QualType Type = VD->getType().getNonReferenceType();
2892
9.49k
          const DSAStackTy::DSAVarData DVar =
2893
9.49k
              DSAStack->getTopDSA(VD, /*FromParent=*/false);
2894
9.49k
          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
8.57k
            VarDecl *VDPrivate = buildVarDecl(
2901
8.57k
                *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2902
8.57k
                VD->getName(), VD->hasAttrs() ? 
&VD->getAttrs()92
:
nullptr8.48k
, DRE);
2903
8.57k
            ActOnUninitializedDecl(VDPrivate);
2904
8.57k
            if (VDPrivate->isInvalidDecl()) {
2905
0
              PrivateCopies.push_back(nullptr);
2906
0
              continue;
2907
0
            }
2908
8.57k
            PrivateCopies.push_back(buildDeclRefExpr(
2909
8.57k
                *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2910
8.57k
          } else {
2911
            // The variable is also a firstprivate, so initialization sequence
2912
            // for private copy is generated already.
2913
927
            PrivateCopies.push_back(nullptr);
2914
927
          }
2915
9.49k
        }
2916
6.93k
        Clause->setPrivateCopies(PrivateCopies);
2917
6.93k
        continue;
2918
6.93k
      }
2919
      // Finalize nontemporal clause by handling private copies, if any.
2920
314k
      if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2921
662
        SmallVector<Expr *, 8> PrivateRefs;
2922
1.04k
        for (Expr *RefExpr : Clause->varlists()) {
2923
1.04k
          assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2924
1.04k
          SourceLocation ELoc;
2925
1.04k
          SourceRange ERange;
2926
1.04k
          Expr *SimpleRefExpr = RefExpr;
2927
1.04k
          auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2928
1.04k
          if (Res.second)
2929
            // It will be analyzed later.
2930
112
            PrivateRefs.push_back(RefExpr);
2931
1.04k
          ValueDecl *D = Res.first;
2932
1.04k
          if (!D)
2933
112
            continue;
2934
2935
936
          const DSAStackTy::DSAVarData DVar =
2936
936
              DSAStack->getTopDSA(D, /*FromParent=*/false);
2937
936
          PrivateRefs.push_back(DVar.PrivateCopy ? 
DVar.PrivateCopy20
2938
936
                                                 : 
SimpleRefExpr916
);
2939
936
        }
2940
662
        Clause->setPrivateRefs(PrivateRefs);
2941
662
        continue;
2942
662
      }
2943
313k
      if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2944
870
        for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; 
++I463
) {
2945
463
          OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2946
463
          auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2947
463
          if (!DRE)
2948
0
            continue;
2949
463
          ValueDecl *VD = DRE->getDecl();
2950
463
          if (!VD || !isa<VarDecl>(VD))
2951
81
            continue;
2952
382
          DSAStackTy::DSAVarData DVar =
2953
382
              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
382
          Expr *MapExpr = nullptr;
2959
382
          if (DVar.RefExpr ||
2960
382
              
DSAStack380
->checkMappableExprComponentListsForDecl(
2961
380
                  VD, /*CurrentRegionOnly=*/true,
2962
380
                  [VD, &MapExpr](
2963
380
                      OMPClauseMappableExprCommon::MappableExprComponentListRef
2964
380
                          MapExprComponents,
2965
380
                      OpenMPClauseKind C) {
2966
2
                    auto MI = MapExprComponents.rbegin();
2967
2
                    auto ME = MapExprComponents.rend();
2968
2
                    if (MI != ME &&
2969
2
                        MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2970
2
                            VD->getCanonicalDecl()) {
2971
2
                      MapExpr = MI->getAssociatedExpression();
2972
2
                      return true;
2973
2
                    }
2974
0
                    return false;
2975
4
                  })) {
2976
4
            Diag(D.Allocator->getExprLoc(),
2977
4
                 diag::err_omp_allocator_used_in_clauses)
2978
4
                << D.Allocator->getSourceRange();
2979
4
            if (DVar.RefExpr)
2980
2
              reportOriginalDsa(*this, DSAStack, VD, DVar);
2981
2
            else
2982
2
              Diag(MapExpr->getExprLoc(), diag::note_used_here)
2983
2
                  << MapExpr->getSourceRange();
2984
4
          }
2985
382
        }
2986
407
        continue;
2987
407
      }
2988
313k
    }
2989
    // Check allocate clauses.
2990
461k
    if (!CurContext->isDependentContext())
2991
338k
      checkAllocateClauses(*this, DSAStack, D->clauses());
2992
461k
    checkReductionClauses(*this, DSAStack, D->clauses());
2993
461k
  }
2994
2995
543k
  DSAStack->pop();
2996
543k
  DiscardCleanupsInEvaluationContext();
2997
543k
  PopExpressionEvaluationContext();
2998
543k
}
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
40
  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
3012
16
  bool ValidateCandidate(const TypoCorrection &Candidate) override {
3013
16
    NamedDecl *ND = Candidate.getCorrectionDecl();
3014
16
    if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3015
16
      return VD->hasGlobalStorage() &&
3016
16
             SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3017
16
                                   SemaRef.getCurScope());
3018
16
    }
3019
0
    return false;
3020
16
  }
3021
3022
40
  std::unique_ptr<CorrectionCandidateCallback> clone() override {
3023
40
    return std::make_unique<VarDeclFilterCCC>(*this);
3024
40
  }
3025
};
3026
3027
class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
3028
private:
3029
  Sema &SemaRef;
3030
3031
public:
3032
27
  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
3033
27
  bool ValidateCandidate(const TypoCorrection &Candidate) override {
3034
27
    NamedDecl *ND = Candidate.getCorrectionDecl();
3035
27
    if (ND && 
(0
(0
isa<VarDecl>(ND)0
&&
ND->getKind() == Decl::Var0
) ||
3036
0
               isa<FunctionDecl>(ND))) {
3037
0
      return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3038
0
                                   SemaRef.getCurScope());
3039
0
    }
3040
27
    return false;
3041
27
  }
3042
3043
27
  std::unique_ptr<CorrectionCandidateCallback> clone() override {
3044
27
    return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
3045
27
  }
3046
};
3047
3048
} // namespace
3049
3050
ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
3051
                                         CXXScopeSpec &ScopeSpec,
3052
                                         const DeclarationNameInfo &Id,
3053
5.04k
                                         OpenMPDirectiveKind Kind) {
3054
5.04k
  LookupResult Lookup(*this, Id, LookupOrdinaryName);
3055
5.04k
  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
3056
3057
5.04k
  if (Lookup.isAmbiguous())
3058
8
    return ExprError();
3059
3060
5.03k
  VarDecl *VD;
3061
5.03k
  if (!Lookup.isSingleResult()) {
3062
40
    VarDeclFilterCCC CCC(*this);
3063
40
    if (TypoCorrection Corrected =
3064
40
            CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
3065
40
                        CTK_ErrorRecovery)) {
3066
8
      diagnoseTypo(Corrected,
3067
8
                   PDiag(Lookup.empty()
3068
8
                             ? diag::err_undeclared_var_use_suggest
3069
8
                             : 
diag::err_omp_expected_var_arg_suggest0
)
3070
8
                       << Id.getName());
3071
8
      VD = Corrected.getCorrectionDeclAs<VarDecl>();
3072
32
    } else {
3073
32
      Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
3074
32
                                       : 
diag::err_omp_expected_var_arg0
)
3075
32
          << Id.getName();
3076
32
      return ExprError();
3077
32
    }
3078
4.99k
  } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
3079
16
    Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
3080
16
    Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
3081
16
    return ExprError();
3082
16
  }
3083
4.98k
  Lookup.suppressDiagnostics();
3084
3085
  // OpenMP [2.9.2, Syntax, C/C++]
3086
  //   Variables must be file-scope, namespace-scope, or static block-scope.
3087
4.98k
  if (Kind == OMPD_threadprivate && 
!VD->hasGlobalStorage()4.20k
) {
3088
8
    Diag(Id.getLoc(), diag::err_omp_global_var_arg)
3089
8
        << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
3090
8
    bool IsDecl =
3091
8
        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3092
8
    Diag(VD->getLocation(),
3093
8
         IsDecl ? 
diag::note_previous_decl0
: diag::note_defined_here)
3094
8
        << VD;
3095
8
    return ExprError();
3096
8
  }
3097
3098
4.97k
  VarDecl *CanonicalVD = VD->getCanonicalDecl();
3099
4.97k
  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
4.97k
  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
3104
4.97k
      
!getCurLexicalContext()->isTranslationUnit()2.53k
) {
3105
16
    Diag(Id.getLoc(), diag::err_omp_var_scope)
3106
16
        << getOpenMPDirectiveName(Kind) << VD;
3107
16
    bool IsDecl =
3108
16
        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3109
16
    Diag(VD->getLocation(),
3110
16
         IsDecl ? 
diag::note_previous_decl0
: diag::note_defined_here)
3111
16
        << VD;
3112
16
    return ExprError();
3113
16
  }
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
4.96k
  if (CanonicalVD->isStaticDataMember() &&
3119
4.96k
      
!CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())208
) {
3120
8
    Diag(Id.getLoc(), diag::err_omp_var_scope)
3121
8
        << getOpenMPDirectiveName(Kind) << VD;
3122
8
    bool IsDecl =
3123
8
        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3124
8
    Diag(VD->getLocation(),
3125
8
         IsDecl ? diag::note_previous_decl : 
diag::note_defined_here0
)
3126
8
        << VD;
3127
8
    return ExprError();
3128
8
  }
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
4.95k
  if (CanonicalVD->getDeclContext()->isNamespace() &&
3134
4.95k
      
(1.50k
!getCurLexicalContext()->isFileContext()1.50k
||
3135
1.50k
       !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
4.95k
  if (CanonicalVD->isLocalVarDecl() && 
CurScope699
&&
3149
4.95k
      
!isDeclInScope(ND, getCurLexicalContext(), CurScope)699
) {
3150
8
    Diag(Id.getLoc(), diag::err_omp_var_scope)
3151
8
        << getOpenMPDirectiveName(Kind) << VD;
3152
8
    bool IsDecl =
3153
8
        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3154
8
    Diag(VD->getLocation(),
3155
8
         IsDecl ? 
diag::note_previous_decl0
: diag::note_defined_here)
3156
8
        << VD;
3157
8
    return ExprError();
3158
8
  }
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
4.94k
  if (Kind == OMPD_threadprivate && 
VD->isUsed()4.18k
&&
3164
4.94k
      
!85
DSAStack85
->isThreadPrivate(VD)) {
3165
4
    Diag(Id.getLoc(), diag::err_omp_var_used)
3166
4
        << getOpenMPDirectiveName(Kind) << VD;
3167
4
    return ExprError();
3168
4
  }
3169
3170
4.94k
  QualType ExprType = VD->getType().getNonReferenceType();
3171
4.94k
  return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
3172
4.94k
                             SourceLocation(), VD,
3173
4.94k
                             /*RefersToEnclosingVariableOrCapture=*/false,
3174
4.94k
                             Id.getLoc(), ExprType, VK_LValue);
3175
4.94k
}
3176
3177
Sema::DeclGroupPtrTy
3178
Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
3179
4.05k
                                        ArrayRef<Expr *> VarList) {
3180
4.05k
  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
3181
3.98k
    CurContext->addDecl(D);
3182
3.98k
    return DeclGroupPtrTy::make(DeclGroupRef(D));
3183
3.98k
  }
3184
68
  return nullptr;
3185
4.05k
}
3186
3187
namespace {
3188
class LocalVarRefChecker final
3189
    : public ConstStmtVisitor<LocalVarRefChecker, bool> {
3190
  Sema &SemaRef;
3191
3192
public:
3193
23
  bool VisitDeclRefExpr(const DeclRefExpr *E) {
3194
23
    if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3195
16
      if (VD->hasLocalStorage()) {
3196
4
        SemaRef.Diag(E->getBeginLoc(),
3197
4
                     diag::err_omp_local_var_in_threadprivate_init)
3198
4
            << E->getSourceRange();
3199
4
        SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
3200
4
            << VD << VD->getSourceRange();
3201
4
        return true;
3202
4
      }
3203
16
    }
3204
19
    return false;
3205
23
  }
3206
2.65k
  bool VisitStmt(const Stmt *S) {
3207
2.65k
    for (const Stmt *Child : S->children()) {
3208
762
      if (Child && Visit(Child))
3209
8
        return true;
3210
762
    }
3211
2.64k
    return false;
3212
2.65k
  }
3213
1.91k
  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
3214
};
3215
} // namespace
3216
3217
OMPThreadPrivateDecl *
3218
4.36k
Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
3219
4.36k
  SmallVector<Expr *, 8> Vars;
3220
4.51k
  for (Expr *RefExpr : VarList) {
3221
4.51k
    auto *DE = cast<DeclRefExpr>(RefExpr);
3222
4.51k
    auto *VD = cast<VarDecl>(DE->getDecl());
3223
4.51k
    SourceLocation ILoc = DE->getExprLoc();
3224
3225
    // Mark variable as used.
3226
4.51k
    VD->setReferenced();
3227
4.51k
    VD->markUsed(Context);
3228
3229
4.51k
    QualType QType = VD->getType();
3230
4.51k
    if (QType->isDependentType() || 
QType->isInstantiationDependentType()4.28k
) {
3231
      // It will be analyzed later.
3232
224
      Vars.push_back(DE);
3233
224
      continue;
3234
224
    }
3235
3236
    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3237
    //   A threadprivate variable must not have an incomplete type.
3238
4.28k
    if (RequireCompleteType(ILoc, VD->getType(),
3239
4.28k
                            diag::err_omp_threadprivate_incomplete_type)) {
3240
4
      continue;
3241
4
    }
3242
3243
    // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3244
    //   A threadprivate variable must not have a reference type.
3245
4.28k
    if (VD->getType()->isReferenceType()) {
3246
4
      Diag(ILoc, diag::err_omp_ref_type_arg)
3247
4
          << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3248
4
      bool IsDecl =
3249
4
          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3250
4
      Diag(VD->getLocation(),
3251
4
           IsDecl ? 
diag::note_previous_decl0
: diag::note_defined_here)
3252
4
          << VD;
3253
4
      continue;
3254
4
    }
3255
3256
    // Check if this is a TLS variable. If TLS is not being supported, produce
3257
    // the corresponding diagnostic.
3258
4.27k
    if ((VD->getTLSKind() != VarDecl::TLS_None &&
3259
4.27k
         
!(42
VD->hasAttr<OMPThreadPrivateDeclAttr>()42
&&
3260
42
           
getLangOpts().OpenMPUseTLS38
&&
3261
42
           
getASTContext().getTargetInfo().isTLSSupported()38
)) ||
3262
4.27k
        
(4.27k
VD->getStorageClass() == SC_Register4.27k
&&
VD->hasAttr<AsmLabelAttr>()4
&&
3263
4.27k
         
!VD->isLocalVarDecl()4
)) {
3264
8
      Diag(ILoc, diag::err_omp_var_thread_local)
3265
8
          << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 
04
:
14
);
3266
8
      bool IsDecl =
3267
8
          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3268
8
      Diag(VD->getLocation(),
3269
8
           IsDecl ? 
diag::note_previous_decl0
: diag::note_defined_here)
3270
8
          << VD;
3271
8
      continue;
3272
8
    }
3273
3274
    // Check if initial value of threadprivate variable reference variable with
3275
    // local storage (it is not supported by runtime).
3276
4.27k
    if (const Expr *Init = VD->getAnyInitializer()) {
3277
1.91k
      LocalVarRefChecker Checker(*this);
3278
1.91k
      if (Checker.Visit(Init))
3279
4
        continue;
3280
1.91k
    }
3281
3282
4.26k
    Vars.push_back(RefExpr);
3283
4.26k
    DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3284
4.26k
    VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3285
4.26k
        Context, SourceRange(Loc, Loc)));
3286
4.26k
    if (ASTMutationListener *ML = Context.getASTMutationListener())
3287
241
      ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3288
4.26k
  }
3289
4.36k
  OMPThreadPrivateDecl *D = nullptr;
3290
4.36k
  if (!Vars.empty()) {
3291
4.29k
    D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3292
4.29k
                                     Vars);
3293
4.29k
    D->setAccess(AS_public);
3294
4.29k
  }
3295
4.36k
  return D;
3296
4.36k
}
3297
3298
static OMPAllocateDeclAttr::AllocatorTypeTy
3299
3.67k
getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3300
3.67k
  if (!Allocator)
3301
1.19k
    return OMPAllocateDeclAttr::OMPNullMemAlloc;
3302
2.47k
  if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3303
2.47k
      Allocator->isInstantiationDependent() ||
3304
2.47k
      Allocator->containsUnexpandedParameterPack())
3305
0
    return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3306
2.47k
  auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3307
2.47k
  llvm::FoldingSetNodeID AEId;
3308
2.47k
  const Expr *AE = Allocator->IgnoreParenImpCasts();
3309
2.47k
  AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3310
19.3k
  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 
++I16.8k
) {
3311
19.2k
    auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3312
19.2k
    const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3313
19.2k
    llvm::FoldingSetNodeID DAEId;
3314
19.2k
    DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
3315
19.2k
                                            /*Canonical=*/true);
3316
19.2k
    if (AEId == DAEId) {
3317
2.39k
      AllocatorKindRes = AllocatorKind;
3318
2.39k
      break;
3319
2.39k
    }
3320
19.2k
  }
3321
2.47k
  return AllocatorKindRes;
3322
2.47k
}
3323
3324
static bool checkPreviousOMPAllocateAttribute(
3325
    Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3326
3.00k
    OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3327
3.00k
  if (!VD->hasAttr<OMPAllocateDeclAttr>())
3328
2.83k
    return false;
3329
170
  const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3330
170
  Expr *PrevAllocator = A->getAllocator();
3331
170
  OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3332
170
      getAllocatorKind(S, Stack, PrevAllocator);
3333
170
  bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3334
170
  if (AllocatorsMatch &&
3335
170
      
AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc164
&&
3336
170
      
Allocator0
&&
PrevAllocator0
) {
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
170
  if (!AllocatorsMatch) {
3345
6
    SmallString<256> AllocatorBuffer;
3346
6
    llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3347
6
    if (Allocator)
3348
4
      Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3349
6
    SmallString<256> PrevAllocatorBuffer;
3350
6
    llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3351
6
    if (PrevAllocator)
3352
4
      PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3353
4
                                 S.getPrintingPolicy());
3354
3355
6
    SourceLocation AllocatorLoc =
3356
6
        Allocator ? 
Allocator->getExprLoc()4
:
RefExpr->getExprLoc()2
;
3357
6
    SourceRange AllocatorRange =
3358
6
        Allocator ? 
Allocator->getSourceRange()4
:
RefExpr->getSourceRange()2
;
3359
6
    SourceLocation PrevAllocatorLoc =
3360
6
        PrevAllocator ? 
PrevAllocator->getExprLoc()4
:
A->getLocation()2
;
3361
6
    SourceRange PrevAllocatorRange =
3362
6
        PrevAllocator ? 
PrevAllocator->getSourceRange()4
:
A->getRange()2
;
3363
6
    S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3364
6
        << (Allocator ? 
14
:
02
) << AllocatorStream.str()
3365
6
        << (PrevAllocator ? 
14
:
02
) << PrevAllocatorStream.str()
3366
6
        << AllocatorRange;
3367
6
    S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3368
6
        << PrevAllocatorRange;
3369
6
    return true;
3370
6
  }
3371
164
  return false;
3372
170
}
3373
3374
static void
3375
applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3376
                          OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3377
2.99k
                          Expr *Allocator, Expr *Alignment, SourceRange SR) {
3378
2.99k
  if (VD->hasAttr<OMPAllocateDeclAttr>())
3379
164
    return;
3380
2.82k
  if (Alignment &&
3381
2.82k
      
(87
Alignment->isTypeDependent()87
||
Alignment->isValueDependent()87
||
3382
87
       
Alignment->isInstantiationDependent()80
||
3383
87
       
Alignment->containsUnexpandedParameterPack()80
))
3384
    // Apply later when we have a usable value.
3385
7
    return;
3386
2.82k
  if (Allocator &&
3387
2.82k
      
(1.86k
Allocator->isTypeDependent()1.86k
||
Allocator->isValueDependent()1.86k
||
3388
1.86k
       Allocator->isInstantiationDependent() ||
3389
1.86k
       Allocator->containsUnexpandedParameterPack()))
3390
0
    return;
3391
2.82k
  auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3392
2.82k
                                                Allocator, Alignment, SR);
3393
2.82k
  VD->addAttr(A);
3394
2.82k
  if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3395
292
    ML->DeclarationMarkedOpenMPAllocate(VD, A);
3396
2.82k
}
3397
3398
Sema::DeclGroupPtrTy
3399
Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
3400
                                   ArrayRef<OMPClause *> Clauses,
3401
805
                                   DeclContext *Owner) {
3402
805
  assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3403
805
  Expr *Alignment = nullptr;
3404
805
  Expr *Allocator = nullptr;
3405
805
  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
319
    if (LangOpts.OpenMPIsTargetDevice &&
3411
319
        
!4
DSAStack4
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3412
2
      targetDiag(Loc, diag::err_expected_allocator_clause);
3413
486
  } else {
3414
486
    for (const OMPClause *C : Clauses)
3415
536
      if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3416
460
        Allocator = AC->getAllocator();
3417
76
      else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3418
76
        Alignment = AC->getAlignment();
3419
0
      else
3420
0
        llvm_unreachable("Unexpected clause on allocate directive");
3421
486
  }
3422
805
  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3423
805
      getAllocatorKind(*this, DSAStack, Allocator);
3424
805
  SmallVector<Expr *, 8> Vars;
3425
842
  for (Expr *RefExpr : VarList) {
3426
842
    auto *DE = cast<DeclRefExpr>(RefExpr);
3427
842
    auto *VD = cast<VarDecl>(DE->getDecl());
3428
3429
    // Check if this is a TLS variable or global register.
3430
842
    if (VD->getTLSKind() != VarDecl::TLS_None ||
3431
842
        
VD->hasAttr<OMPThreadPrivateDeclAttr>()838
||
3432
842
        
(838
VD->getStorageClass() == SC_Register838
&&
VD->hasAttr<AsmLabelAttr>()4
&&
3433
838
         
!VD->isLocalVarDecl()4
))
3434
8
      continue;
3435
3436
    // If the used several times in the allocate directive, the same allocator
3437
    // must be used.
3438
834
    if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3439
834
                                          AllocatorKind, Allocator))
3440
6
      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
828
    if (Allocator && 
VD->hasGlobalStorage()499
) {
3447
259
      if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3448
4
        Diag(Allocator->getExprLoc(),
3449
4
             diag::err_omp_expected_predefined_allocator)
3450
4
            << Allocator->getSourceRange();
3451
4
        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3452
4
                      VarDecl::DeclarationOnly;
3453
4
        Diag(VD->getLocation(),
3454
4
             IsDecl ? 
diag::note_previous_decl0
: diag::note_defined_here)
3455
4
            << VD;
3456
4
        continue;
3457
4
      }
3458
259
    }
3459
3460
824
    Vars.push_back(RefExpr);
3461
824
    applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3462
824
                              DE->getSourceRange());
3463
824
  }
3464
805
  if (Vars.empty())
3465
58
    return nullptr;
3466
747
  if (!Owner)
3467
665
    Owner = getCurLexicalContext();
3468
747
  auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3469
747
  D->setAccess(AS_public);
3470
747
  Owner->addDecl(D);
3471
747
  return DeclGroupPtrTy::make(DeclGroupRef(D));
3472
805
}
3473
3474
Sema::DeclGroupPtrTy
3475
Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3476
266
                                   ArrayRef<OMPClause *> ClauseList) {
3477
266
  OMPRequiresDecl *D = nullptr;
3478
266
  if (!CurContext->isFileContext()) {
3479
2
    Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3480
264
  } else {
3481
264
    D = CheckOMPRequiresDecl(Loc, ClauseList);
3482
264
    if (D) {
3483
238
      CurContext->addDecl(D);
3484
238
      DSAStack->addRequiresDecl(D);
3485
238
    }
3486
264
  }
3487
266
  return DeclGroupPtrTy::make(DeclGroupRef(D));
3488
266
}
3489
3490
void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3491
                                       OpenMPDirectiveKind DKind,
3492
                                       ArrayRef<std::string> Assumptions,
3493
207
                                       bool SkippedClauses) {
3494
207
  if (!SkippedClauses && 
Assumptions.empty()117
)
3495
8
    Diag(Loc, diag::err_omp_no_clause_for_directive)
3496
8
        << llvm::omp::getAllAssumeClauseOptions()
3497
8
        << llvm::omp::getOpenMPDirectiveName(DKind);
3498
3499
207
  auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3500
207
  if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3501
124
    OMPAssumeScoped.push_back(AA);
3502
124
    return;
3503
124
  }
3504
3505
  // Global assumes without assumption clauses are ignored.
3506
83
  if (Assumptions.empty())
3507
32
    return;
3508
3509
51
  assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3510
51
         "Unexpected omp assumption directive!");
3511
51
  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
51
  SmallVector<DeclContext *, 8> DeclContexts;
3518
51
  auto *Ctx = CurContext;
3519
55
  while (Ctx->getLexicalParent())
3520
4
    Ctx = Ctx->getLexicalParent();
3521
51
  DeclContexts.push_back(Ctx);
3522
5.76k
  while (!DeclContexts.empty()) {
3523
5.71k
    DeclContext *DC = DeclContexts.pop_back_val();
3524
9.34k
    for (auto *SubDC : DC->decls()) {
3525
9.34k
      if (SubDC->isInvalidDecl())
3526
0
        continue;
3527
9.34k
      if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3528
4
        DeclContexts.push_back(CTD->getTemplatedDecl());
3529
4
        llvm::append_range(DeclContexts, CTD->specializations());
3530
4
        continue;
3531
4
      }
3532
9.34k
      if (auto *DC = dyn_cast<DeclContext>(SubDC))
3533
5.65k
        DeclContexts.push_back(DC);
3534
9.34k
      if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3535
5.32k
        F->addAttr(AA);
3536
5.32k
        continue;
3537
5.32k
      }
3538
9.34k
    }
3539
5.71k
  }
3540
51
}
3541
3542
120
void Sema::ActOnOpenMPEndAssumesDirective() {
3543
120
  assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3544
120
  OMPAssumeScoped.pop_back();
3545
120
}
3546
3547
OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3548
264
                                            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
264
  ArrayRef<SourceLocation> TargetLocations =
3553
264
      DSAStack->getEncounteredTargetLocs();
3554
264
  SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3555
264
  if (!TargetLocations.empty() || 
!AtomicLoc.isInvalid()255
) {
3556
12
    for (const OMPClause *CNew : ClauseList) {
3557
      // Check if any of the requires clauses affect target regions.
3558
12
      if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3559
12
          
isa<OMPUnifiedAddressClause>(CNew)10
||
3560
12
          
isa<OMPReverseOffloadClause>(CNew)8
||
3561
12
          
isa<OMPDynamicAllocatorsClause>(CNew)7
) {
3562
7
        Diag(Loc, diag::err_omp_directive_before_requires)
3563
7
            << "target" << getOpenMPClauseName(CNew->getClauseKind());
3564
7
        for (SourceLocation TargetLoc : TargetLocations) {
3565
7
          Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3566
7
              << "target";
3567
7
        }
3568
7
      } else 
if (5
!AtomicLoc.isInvalid()5
&&
3569
5
                 
isa<OMPAtomicDefaultMemOrderClause>(CNew)3
) {
3570
3
        Diag(Loc, diag::err_omp_directive_before_requires)
3571
3
            << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3572
3
        Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3573
3
            << "atomic";
3574
3
      }
3575
12
    }
3576
12
  }
3577
3578
264
  if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3579
238
    return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3580
238
                                   ClauseList);
3581
26
  return nullptr;
3582
264
}
3583
3584
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3585
                              const ValueDecl *D,
3586
                              const DSAStackTy::DSAVarData &DVar,
3587
9.13k
                              bool IsLoopIterVar) {
3588
9.13k
  if (DVar.RefExpr) {
3589
6.75k
    SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3590
6.75k
        << getOpenMPClauseName(DVar.CKind);
3591
6.75k
    return;
3592
6.75k
  }
3593
2.38k
  enum {
3594
2.38k
    PDSA_StaticMemberShared,
3595
2.38k
    PDSA_StaticLocalVarShared,
3596
2.38k
    PDSA_LoopIterVarPrivate,
3597
2.38k
    PDSA_LoopIterVarLinear,
3598
2.38k
    PDSA_LoopIterVarLastprivate,
3599
2.38k
    PDSA_ConstVarShared,
3600
2.38k
    PDSA_GlobalVarShared,
3601
2.38k
    PDSA_TaskVarFirstprivate,
3602
2.38k
    PDSA_LocalVarPrivate,
3603
2.38k
    PDSA_Implicit
3604
2.38k
  } Reason = PDSA_Implicit;
3605
2.38k
  bool ReportHint = false;
3606
2.38k
  auto ReportLoc = D->getLocation();
3607
2.38k
  auto *VD = dyn_cast<VarDecl>(D);
3608
2.38k
  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
2.38k
  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3616
2.38k
             
DVar.CKind == OMPC_firstprivate12
) {
3617
12
    Reason = PDSA_TaskVarFirstprivate;
3618
12
    ReportLoc = DVar.ImplicitDSALoc;
3619
2.36k
  } else if (VD && VD->isStaticLocal())
3620
0
    Reason = PDSA_StaticLocalVarShared;
3621
2.36k
  else if (VD && VD->isStaticDataMember())
3622
2.21k
    Reason = PDSA_StaticMemberShared;
3623
150
  else if (VD && VD->isFileVarDecl())
3624
0
    Reason = PDSA_GlobalVarShared;
3625
150
  else if (D->getType().isConstant(SemaRef.getASTContext()))
3626
0
    Reason = PDSA_ConstVarShared;
3627
150
  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3628
62
    ReportHint = true;
3629
62
    Reason = PDSA_LocalVarPrivate;
3630
62
  }
3631
2.38k
  if (Reason != PDSA_Implicit) {
3632
2.29k
    SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3633
2.29k
        << Reason << ReportHint
3634
2.29k
        << getOpenMPDirectiveName(Stack->getCurrentDirective());
3635
2.29k
  } else 
if (88
DVar.ImplicitDSALoc.isValid()88
) {
3636
12
    SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3637
12
        << getOpenMPClauseName(DVar.CKind);
3638
12
  }
3639
2.38k
}
3640
3641
static OpenMPMapClauseKind
3642
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3643
20.6k
                             bool IsAggregateOrDeclareTarget) {
3644
20.6k
  OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3645
20.6k
  switch (M) {
3646
40
  case OMPC_DEFAULTMAP_MODIFIER_alloc:
3647
40
    Kind = OMPC_MAP_alloc;
3648
40
    break;
3649
32
  case OMPC_DEFAULTMAP_MODIFIER_to:
3650
32
    Kind = OMPC_MAP_to;
3651
32
    break;
3652
32
  case OMPC_DEFAULTMAP_MODIFIER_from:
3653
32
    Kind = OMPC_MAP_from;
3654
32
    break;
3655
348
  case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3656
348
    Kind = OMPC_MAP_tofrom;
3657
348
    break;
3658
32
  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
32
    Kind = OMPC_MAP_alloc;
3665
32
    break;
3666
0
  case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3667
0
  case OMPC_DEFAULTMAP_MODIFIER_last:
3668
0
    llvm_unreachable("Unexpected defaultmap implicit behavior");
3669
24
  case OMPC_DEFAULTMAP_MODIFIER_none:
3670
32
  case OMPC_DEFAULTMAP_MODIFIER_default:
3671
20.1k
  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
20.1k
    if (IsAggregateOrDeclareTarget) {
3676
20.1k
      Kind = OMPC_MAP_tofrom;
3677
20.1k
      break;
3678
20.1k
    }
3679
20.6k
    
llvm_unreachable0
("Unexpected defaultmap implicit behavior");
3680
20.6k
  }
3681
20.6k
  assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3682
20.6k
  return Kind;
3683
20.6k
}
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_pointer + 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
101k
  void VisitSubCaptures(OMPExecutableDirective *S) {
3702
    // Check implicitly captured variables.
3703
101k
    if (!S->hasAssociatedStmt() || 
!S->getAssociatedStmt()98.5k
)
3704
2.59k
      return;
3705
98.5k
    if (S->getDirectiveKind() == OMPD_atomic ||
3706
98.5k
        
S->getDirectiveKind() == OMPD_critical98.0k
||
3707
98.5k
        
S->getDirectiveKind() == OMPD_section97.5k
||
3708
98.5k
        
S->getDirectiveKind() == OMPD_master96.7k
||
3709
98.5k
        
S->getDirectiveKind() == OMPD_masked96.4k
||
3710
98.5k
        
S->getDirectiveKind() == OMPD_scope96.4k
||
3711
98.5k
        
isOpenMPLoopTransformationDirective(S->getDirectiveKind())96.4k
) {
3712
2.19k
      Visit(S->getAssociatedStmt());
3713
2.19k
      return;
3714
2.19k
    }
3715
96.4k
    visitSubCaptures(S->getInnermostCapturedStmt());
3716
    // Try to capture inner this->member references to generate correct mappings
3717
    // and diagnostics.
3718
96.4k
    if (TryCaptureCXXThisMembers ||
3719
96.4k
        
(96.2k
isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())96.2k
&&
3720
96.2k
         llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3721
39.1k
                      [](const CapturedStmt::Capture &C) {
3722
33.6k
                        return C.capturesThis();
3723
33.6k
                      }))) {
3724
782
      bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3725
782
      TryCaptureCXXThisMembers = true;
3726
782
      Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3727
782
      TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3728
782
    }
3729
    // In tasks firstprivates are not captured anymore, need to analyze them
3730
    // explicitly.
3731
96.4k
    if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3732
96.4k
        
!isOpenMPTaskLoopDirective(S->getDirectiveKind())14.7k
) {
3733
1.85k
      for (OMPClause *C : S->clauses())
3734
1.65k
        if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3735
890
          for (Expr *Ref : FC->varlists())
3736
1.35k
            Visit(Ref);
3737
890
        }
3738
1.85k
    }
3739
96.4k
  }
3740
3741
public:
3742
1.09M
  void VisitDeclRefExpr(DeclRefExpr *E) {
3743
1.09M
    if (TryCaptureCXXThisMembers || 
E->isTypeDependent()1.09M
||
3744
1.09M
        
E->isValueDependent()1.09M
||
E->containsUnexpandedParameterPack()1.09M
||
3745
1.09M
        
E->isInstantiationDependent()1.09M
)
3746
2.28k
      return;
3747
1.09M
    if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3748
      // Check the datasharing rules for the expressions in the clauses.
3749
959k
      if (!CS || 
(959k
isa<OMPCapturedExprDecl>(VD)959k
&&
!CS->capturesVariable(VD)10.0k
&&
3750
959k
                  
!Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr3.63k
&&
3751
959k
                  
!Stack->isImplicitDefaultFirstprivateFD(VD)1.88k
)) {
3752
2.18k
        if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3753
2.01k
          if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3754
1.96k
            Visit(CED->getInit());
3755
1.96k
            return;
3756
1.96k
          }
3757
957k
      } else if (VD->isImplicit() || 
isa<OMPCapturedExprDecl>(VD)947k
)
3758
        // Do not analyze internal variables and do not enclose them into
3759
        // implicit clauses.
3760
10.1k
        if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3761
10.0k
          return;
3762
947k
      VD = VD->getCanonicalDecl();
3763
      // Skip internally declared variables.
3764
947k
      if (VD->hasLocalStorage() && 
CS894k
&&
!CS->capturesVariable(VD)893k
&&
3765
947k
          
!Stack->isImplicitDefaultFirstprivateFD(VD)404k
&&
3766
947k
          
!Stack->isImplicitTaskFirstprivate(VD)404k
)
3767
394k
        return;
3768
      // Skip allocators in uses_allocators clauses.
3769
553k
      if (Stack->isUsesAllocatorsDecl(VD))
3770
268
        return;
3771
3772
552k
      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3773
      // Check if the variable has explicit DSA set and stop analysis if it so.
3774
552k
      if (DVar.RefExpr || 
!ImplicitDeclarations.insert(VD).second387k
)
3775
362k
        return;
3776
3777
      // Skip internally declared static variables.
3778
190k
      std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3779
190k
          OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3780
190k
      if (VD->hasGlobalStorage() && 
CS14.9k
&&
!CS->capturesVariable(VD)14.9k
&&
3781
190k
          
(3.98k
Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>()3.98k
||
3782
3.98k
           
!Res3.97k
||
*Res != OMPDeclareTargetDeclAttr::MT_Link102
) &&
3783
190k
          
!Stack->isImplicitDefaultFirstprivateFD(VD)3.93k
&&
3784
190k
          
!Stack->isImplicitTaskFirstprivate(VD)3.92k
)
3785
3.90k
        return;
3786
3787
186k
      SourceLocation ELoc = E->getExprLoc();
3788
186k
      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
186k
      if (DVar.CKind == OMPC_unknown &&
3794
186k
          
(185k
Stack->getDefaultDSA() == DSA_none185k
||
3795
185k
           
Stack->getDefaultDSA() == DSA_private185k
||
3796
185k
           
Stack->getDefaultDSA() == DSA_firstprivate185k
) &&
3797
186k
          
isImplicitOrExplicitTaskingRegion(DKind)628
&&
3798
186k
          
VarsWithInheritedDSA.count(VD) == 0628
) {
3799
628
        bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3800
628
        if (!InheritedDSA && 
(180
Stack->getDefaultDSA() == DSA_firstprivate180
||
3801
180
                              
Stack->getDefaultDSA() == DSA_private81
)) {
3802
180
          DSAStackTy::DSAVarData DVar =
3803
180
              Stack->getImplicitDSA(VD, /*FromParent=*/false);
3804
180
          InheritedDSA = DVar.CKind == OMPC_unknown;
3805
180
        }
3806
628
        if (InheritedDSA)
3807
560
          VarsWithInheritedDSA[VD] = E;
3808
628
        if (Stack->getDefaultDSA() == DSA_none)
3809
448
          return;
3810
628
      }
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
186k
      OpenMPDefaultmapClauseKind ClauseKind =
3821
186k
          getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3822
186k
      if (SemaRef.getLangOpts().OpenMP >= 50) {
3823
129k
        bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3824
129k
                              OMPC_DEFAULTMAP_MODIFIER_none;
3825
129k
        if (DVar.CKind == OMPC_unknown && 
IsModifierNone129k
&&
3826
129k
            
VarsWithInheritedDSA.count(VD) == 0344
&&
!Res344
) {
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
320
          if (!Stack->checkMappableExprComponentListsForDecl(
3831
320
                  VD, /*CurrentRegionOnly=*/true,
3832
320
                  [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3833
320
                           MapExprComponents,
3834
320
                       OpenMPClauseKind) {
3835
242
                    auto MI = MapExprComponents.rbegin();
3836
242
                    auto ME = MapExprComponents.rend();
3837
242
                    return MI != ME && MI->getAssociatedDeclaration() == VD;
3838
242
                  })) {
3839
78
            VarsWithInheritedDSA[VD] = E;
3840
78
            return;
3841
78
          }
3842
320
        }
3843
129k
      }
3844
185k
      if (SemaRef.getLangOpts().OpenMP > 50) {
3845
117k
        bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3846
117k
                                 OMPC_DEFAULTMAP_MODIFIER_present;
3847
117k
        if (IsModifierPresent) {
3848
32
          if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3849
32
                                  OMPC_MAP_MODIFIER_present)) {
3850
32
            ImplicitMapModifier[ClauseKind].push_back(
3851
32
                OMPC_MAP_MODIFIER_present);
3852
32
          }
3853
32
        }
3854
117k
      }
3855
3856
185k
      if (isOpenMPTargetExecutionDirective(DKind) &&
3857
185k
          
!Stack->isLoopControlVariable(VD).first82.7k
) {
3858
82.7k
        if (!Stack->checkMappableExprComponentListsForDecl(
3859
82.7k
                VD, /*CurrentRegionOnly=*/true,
3860
82.7k
                [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3861
82.7k
                           StackComponents,
3862
82.7k
                       OpenMPClauseKind) {
3863
3.29k
                  if (SemaRef.LangOpts.OpenMP >= 50)
3864
2.57k
                    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
721
                  return StackComponents.size() == 1 ||
3868
721
                         llvm::all_of(
3869
328
                             llvm::drop_begin(llvm::reverse(StackComponents)),
3870
328
                             [](const OMPClauseMappableExprCommon::
3871
440
                                    MappableComponent &MC) {
3872
440
                               return MC.getAssociatedDeclaration() ==
3873
440
                                          nullptr &&
3874
440
                                      
(308
isa<OMPArraySectionExpr>(
3875
308
                                           MC.getAssociatedExpression()) ||
3876
308
                                       isa<OMPArrayShapingExpr>(
3877
92
                                           MC.getAssociatedExpression()) ||
3878
308
                                       isa<ArraySubscriptExpr>(
3879
92
                                           MC.getAssociatedExpression()));
3880
440
                             });
3881
79.6k
                })) {
3882
79.6k
          bool IsFirstprivate = false;
3883
          // By default lambdas are captured as firstprivates.
3884
79.6k
          if (const auto *RD =
3885
79.6k
                  VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3886
7.74k
            IsFirstprivate = RD->isLambda();
3887
79.6k
          IsFirstprivate =
3888
79.6k
              IsFirstprivate || 
(79.5k
Stack->mustBeFirstprivate(ClauseKind)79.5k
&&
!Res60.5k
);
3889
79.6k
          if (IsFirstprivate) {
3890
60.5k
            ImplicitFirstprivate.emplace_back(E);
3891
60.5k
          } else {
3892
19.0k
            OpenMPDefaultmapClauseModifier M =
3893
19.0k
                Stack->getDefaultmapModifier(ClauseKind);
3894
19.0k
            OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3895
19.0k
                M, ClauseKind == OMPC_DEFAULTMAP_aggregate || 
Res444
);
3896
19.0k
            ImplicitMap[ClauseKind][Kind].emplace_back(E);
3897
19.0k
          }
3898
79.6k
          return;
3899
79.6k
        }
3900
82.7k
      }
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
106k
      DVar = Stack->hasInnermostDSA(
3907
106k
          VD,
3908
106k
          [](OpenMPClauseKind C, bool AppliedToPointee) {
3909
24.3k
            return C == OMPC_reduction && 
!AppliedToPointee86
;
3910
24.3k
          },
3911
106k
          [](OpenMPDirectiveKind K) {
3912
59.0k
            return isOpenMPParallelDirective(K) ||
3913
59.0k
                   
isOpenMPWorksharingDirective(K)43.3k
||
isOpenMPTeamsDirective(K)42.9k
;
3914
59.0k
          },
3915
106k
          /*FromParent=*/true);
3916
106k
      if (isOpenMPTaskingDirective(DKind) && 
DVar.CKind == OMPC_reduction17.4k
) {
3917
84
        ErrorFound = true;
3918
84
        SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3919
84
        reportOriginalDsa(SemaRef, Stack, VD, DVar);
3920
84
        return;
3921
84
      }
3922
3923
      // Define implicit data-sharing attributes for task.
3924
106k
      DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3925
106k
      if (((isOpenMPTaskingDirective(DKind) && 
DVar.CKind != OMPC_shared17.3k
) ||
3926
106k
           
(99.5k
(99.5k
(99.5k
Stack->getDefaultDSA() == DSA_firstprivate99.5k
&&
3927
99.5k
              
DVar.CKind == OMPC_firstprivate94
) ||
3928
99.5k
             
(99.5k
Stack->getDefaultDSA() == DSA_private99.5k
&&
3929
99.5k
              
DVar.CKind == OMPC_private77
)) &&
3930
99.5k
            
!DVar.RefExpr75
)) &&
3931
106k
          
!Stack->isLoopControlVariable(VD).first6.75k
) {
3932
6.75k
        if (Stack->getDefaultDSA() == DSA_private)
3933
33
          ImplicitPrivate.push_back(E);
3934
6.72k
        else
3935
6.72k
          ImplicitFirstprivate.push_back(E);
3936
6.75k
        return;
3937
6.75k
      }
3938
3939
      // Store implicitly used globals with declare target link for parent
3940
      // target.
3941
99.4k
      if (!isOpenMPTargetExecutionDirective(DKind) && 
Res96.3k
&&
3942
99.4k
          
*Res == OMPDeclareTargetDeclAttr::MT_Link8
) {
3943
8
        Stack->addToParentTargetRegionLinkGlobals(E);
3944
8
        return;
3945
8
      }
3946
99.4k
    }
3947
1.09M
  }
3948
9.78k
  void VisitMemberExpr(MemberExpr *E) {
3949
9.78k
    if (E->isTypeDependent() || E->isValueDependent() ||
3950
9.78k
        E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3951
0
      return;
3952
9.78k
    auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3953
9.78k
    OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3954
9.78k
    if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3955
3.81k
      if (!FD)
3956
8
        return;
3957
3.81k
      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
3.81k
      if (DVar.RefExpr || 
!ImplicitDeclarations.insert(FD).second3.46k
)
3961
1.13k
        return;
3962
3963
2.67k
      if (isOpenMPTargetExecutionDirective(DKind) &&
3964
2.67k
          
!Stack->isLoopControlVariable(FD).first1.78k
&&
3965
2.67k
          !Stack->checkMappableExprComponentListsForDecl(
3966
1.78k
              FD, /*CurrentRegionOnly=*/true,
3967
1.78k
              [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3968
1.78k
                     StackComponents,
3969
1.78k
                 OpenMPClauseKind) {
3970
157
                return isa<CXXThisExpr>(
3971
157
                    cast<MemberExpr>(
3972
157
                        StackComponents.back().getAssociatedExpression())
3973
157
                        ->getBase()
3974
157
                        ->IgnoreParens());
3975
1.62k
              })) {
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
1.62k
        if (FD->isBitField())
3980
21
          return;
3981
3982
        // Check to see if the member expression is referencing a class that
3983
        // has already been explicitly mapped
3984
1.60k
        if (Stack->isClassPreviouslyMapped(TE->getType()))
3985
34
          return;
3986
3987
1.57k
        OpenMPDefaultmapClauseModifier Modifier =
3988
1.57k
            Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3989
1.57k
        OpenMPDefaultmapClauseKind ClauseKind =
3990
1.57k
            getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3991
1.57k
        OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3992
1.57k
            Modifier, /*IsAggregateOrDeclareTarget*/ true);
3993
1.57k
        ImplicitMap[ClauseKind][Kind].emplace_back(E);
3994
1.57k
        return;
3995
1.60k
      }
3996
3997
1.04k
      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
1.04k
      DVar = Stack->hasInnermostDSA(
4003
1.04k
          FD,
4004
1.04k
          [](OpenMPClauseKind C, bool AppliedToPointee) {
4005
18
            return C == OMPC_reduction && 
!AppliedToPointee0
;
4006
18
          },
4007
1.04k
          [](OpenMPDirectiveKind K) {
4008
436
            return isOpenMPParallelDirective(K) ||
4009
436
                   
isOpenMPWorksharingDirective(K)418
||
isOpenMPTeamsDirective(K)418
;
4010
436
          },
4011
1.04k
          /*FromParent=*/true);
4012
1.04k
      if (isOpenMPTaskingDirective(DKind) && 
DVar.CKind == OMPC_reduction232
) {
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
1.04k
      DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
4021
1.04k
      if (isOpenMPTaskingDirective(DKind) && 
DVar.CKind != OMPC_shared232
&&
4022
1.04k
          
!Stack->isLoopControlVariable(FD).first0
) {
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
1.04k
      return;
4031
1.04k
    }
4032
5.96k
    if (isOpenMPTargetExecutionDirective(DKind)) {
4033
3.24k
      OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
4034
3.24k
      if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
4035
3.24k
                                        Stack->getCurrentDirective(),
4036
3.24k
                                        /*NoDiagnose=*/true))
4037
42
        return;
4038
3.19k
      const auto *VD = cast<ValueDecl>(
4039
3.19k
          CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4040
3.19k
      if (!Stack->checkMappableExprComponentListsForDecl(
4041
3.19k
              VD, /*CurrentRegionOnly=*/true,
4042
3.19k
              [&CurComponents](
4043
3.19k
                  OMPClauseMappableExprCommon::MappableExprComponentListRef
4044
3.19k
                      StackComponents,
4045
3.19k
                  OpenMPClauseKind) {
4046
893
                auto CCI = CurComponents.rbegin();
4047
893
                auto CCE = CurComponents.rend();
4048
1.61k
                for (const auto &SC : llvm::reverse(StackComponents)) {
4049
                  // Do both expressions have the same kind?
4050
1.61k
                  if (CCI->getAssociatedExpression()->getStmtClass() !=
4051
1.61k
                      SC.getAssociatedExpression()->getStmtClass())
4052
84
                    if (!((isa<OMPArraySectionExpr>(
4053
84
                               SC.getAssociatedExpression()) ||
4054
84
                           isa<OMPArrayShapingExpr>(
4055
0
                               SC.getAssociatedExpression())) &&
4056
84
                          isa<ArraySubscriptExpr>(
4057
84
                              CCI->getAssociatedExpression())))
4058
0
                      return false;
4059
4060
1.61k
                  const Decl *CCD = CCI->getAssociatedDeclaration();
4061
1.61k
                  const Decl *SCD = SC.getAssociatedDeclaration();
4062
1.61k
                  CCD = CCD ? 
CCD->getCanonicalDecl()1.52k
:
nullptr84
;
4063
1.61k
                  SCD = SCD ? 
SCD->getCanonicalDecl()1.52k
:
nullptr84
;
4064
1.61k
                  if (SCD != CCD)
4065
431
                    return false;
4066
1.18k
                  std::advance(CCI, 1);
4067
1.18k
                  if (CCI == CCE)
4068
150
                    break;
4069
1.18k
                }
4070
462
                return true;
4071
2.73k
              })) {
4072
2.73k
        Visit(E->getBase());
4073
2.73k
      }
4074
3.19k
    } else 
if (2.72k
!TryCaptureCXXThisMembers2.72k
) {
4075
2.72k
      Visit(E->getBase());
4076
2.72k
    }
4077
5.96k
  }
4078
101k
  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
4079
101k
    for (OMPClause *C : S->clauses()) {
4080
      // Skip analysis of arguments of private clauses for task|target
4081
      // directives.
4082
49.6k
      if (isa_and_nonnull<OMPPrivateClause>(C))
4083
4.01k
        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
45.6k
      if (C && !((isa<OMPFirstprivateClause>(C) || 
isa<OMPMapClause>(C)36.8k
) &&
4089
45.6k
                 
C->isImplicit()13.3k
&&
4090
45.6k
                 
!isOpenMPTaskingDirective(Stack->getCurrentDirective())6.24k
)) {
4091
44.9k
        for (Stmt *CC : C->children()) {
4092
44.9k
          if (CC)
4093
43.9k
            Visit(CC);
4094
44.9k
        }
4095
40.0k
      }
4096
45.6k
    }
4097
    // Check implicitly captured variables.
4098
101k
    VisitSubCaptures(S);
4099
101k
  }
4100
4101
58
  void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
4102
    // Loop transformation directives do not introduce data sharing
4103
58
    VisitStmt(S);
4104
58
  }
4105
4106
136k
  void VisitCallExpr(CallExpr *S) {
4107
136k
    for (Stmt *C : S->arguments()) {
4108
24.9k
      if (C) {
4109
        // Check implicitly captured variables in the task-based directives to
4110
        // check if they must be firstprivatized.
4111
24.9k
        Visit(C);
4112
24.9k
      }
4113
24.9k
    }
4114
136k
    if (Expr *Callee = S->getCallee()) {
4115
136k
      auto *CI = Callee->IgnoreParenImpCasts();
4116
136k
      if (auto *CE = dyn_cast<MemberExpr>(CI))
4117
326
        Visit(CE->getBase());
4118
136k
      else if (auto *CE = dyn_cast<DeclRefExpr>(CI))
4119
135k
        Visit(CE);
4120
136k
    }
4121
136k
  }
4122
1.94M
  void VisitStmt(Stmt *S) {
4123
2.60M
    for (Stmt *C : S->children()) {
4124
2.60M
      if (C) {
4125
        // Check implicitly captured variables in the task-based directives to
4126
        // check if they must be firstprivatized.
4127
2.43M
        Visit(C);
4128
2.43M
      }
4129
2.60M
    }
4130
1.94M
  }
4131
4132
362k
  void visitSubCaptures(CapturedStmt *S) {
4133
362k
    for (const CapturedStmt::Capture &Cap : S->captures()) {
4134
327k
      if (!Cap.capturesVariable() && 
!Cap.capturesVariableByCopy()98.7k
)
4135
9.77k
        continue;
4136
317k
      VarDecl *VD = Cap.getCapturedVar();
4137
      // Do not try to map the variable if it or its sub-component was mapped
4138
      // already.
4139
317k
      if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4140
317k
          Stack->checkMappableExprComponentListsForDecl(
4141
144k
              VD, /*CurrentRegionOnly=*/true,
4142
144k
              [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
4143
144k
                 OpenMPClauseKind) 
{ return true; }4.35k
))
4144
4.35k
        continue;
4145
313k
      DeclRefExpr *DRE = buildDeclRefExpr(
4146
313k
          SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
4147
313k
          Cap.getLocation(), /*RefersToCapture=*/true);
4148
313k
      Visit(DRE);
4149
313k
    }
4150
362k
  }
4151
325k
  bool isErrorFound() const { return ErrorFound; }
4152
651k
  ArrayRef<Expr *> getImplicitFirstprivate() const {
4153
651k
    return ImplicitFirstprivate;
4154
651k
  }
4155
651k
  ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; }
4156
  ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
4157
3.90M
                                  OpenMPMapClauseKind MK) const {
4158
3.90M
    return ImplicitMap[DK][MK];
4159
3.90M
  }
4160
  ArrayRef<OpenMPMapModifierKind>
4161
976k
  getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
4162
976k
    return ImplicitMapModifier[Kind];
4163
976k
  }
4164
327k
  const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
4165
327k
    return VarsWithInheritedDSA;
4166
327k
  }
4167
4168
  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
4169
327k
      : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
4170
    // Process declare target link variables for the target directives.
4171
327k
    if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
4172
124k
      for (DeclRefExpr *E : Stack->getLinkGlobals())
4173
8
        Visit(E);
4174
124k
    }
4175
327k
  }
4176
};
4177
} // namespace
4178
4179
static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
4180
                                               OpenMPDirectiveKind DKind,
4181
1.06M
                                               bool ScopeEntry) {
4182
1.06M
  SmallVector<llvm::omp::TraitProperty, 8> Traits;
4183
1.06M
  if (isOpenMPTargetExecutionDirective(DKind))
4184
371k
    Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4185
1.06M
  if (isOpenMPTeamsDirective(DKind))
4186
240k
    Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4187
1.06M
  if (isOpenMPParallelDirective(DKind))
4188
398k
    Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4189
1.06M
  if (isOpenMPWorksharingDirective(DKind))
4190
278k
    Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4191
1.06M
  if (isOpenMPSimdDirective(DKind))
4192
297k
    Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4193
1.06M
  Stack->handleConstructTrait(Traits, ScopeEntry);
4194
1.06M
}
4195
4196
534k
void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
4197
534k
  switch (DKind) {
4198
50.7k
  case OMPD_parallel:
4199
59.2k
  case OMPD_parallel_for:
4200
68.7k
  case OMPD_parallel_for_simd:
4201
74.8k
  case OMPD_parallel_sections:
4202
80.5k
  case OMPD_parallel_master:
4203
84.8k
  case OMPD_parallel_masked:
4204
84.9k
  case OMPD_parallel_loop:
4205
115k
  case OMPD_teams:
4206
122k
  case OMPD_teams_distribute:
4207
130k
  case OMPD_teams_distribute_simd: {
4208
130k
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4209
130k
    QualType KmpInt32PtrTy =
4210
130k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4211
130k
    Sema::CapturedParamNameType Params[] = {
4212
130k
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4213
130k
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4214
130k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4215
130k
    };
4216
130k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4217
130k
                             Params);
4218
130k
    break;
4219
122k
  }
4220
10.8k
  case OMPD_target_teams:
4221
21.6k
  case OMPD_target_parallel:
4222
33.2k
  case OMPD_target_parallel_for:
4223
44.5k
  case OMPD_target_parallel_for_simd:
4224
45.3k
  case OMPD_target_parallel_loop:
4225
55.7k
  case OMPD_target_teams_distribute:
4226
68.0k
  case OMPD_target_teams_distribute_simd: {
4227
68.0k
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4228
68.0k
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4229
68.0k
    QualType KmpInt32PtrTy =
4230
68.0k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4231
68.0k
    QualType Args[] = {VoidPtrTy};
4232
68.0k
    FunctionProtoType::ExtProtoInfo EPI;
4233
68.0k
    EPI.Variadic = true;
4234
68.0k
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4235
68.0k
    Sema::CapturedParamNameType Params[] = {
4236
68.0k
        std::make_pair(".global_tid.", KmpInt32Ty),
4237
68.0k
        std::make_pair(".part_id.", KmpInt32PtrTy),
4238
68.0k
        std::make_pair(".privates.", VoidPtrTy),
4239
68.0k
        std::make_pair(
4240
68.0k
            ".copy_fn.",
4241
68.0k
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4242
68.0k
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4243
68.0k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4244
68.0k
    };
4245
68.0k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4246
68.0k
                             Params, /*OpenMPCaptureLevel=*/0);
4247
    // Mark this captured region as inlined, because we don't use outlined
4248
    // function directly.
4249
68.0k
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4250
68.0k
        AlwaysInlineAttr::CreateImplicit(
4251
68.0k
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4252
68.0k
    SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4253
68.0k
    if (getLangOpts().OpenMPIsTargetDevice)
4254
2.19k
      ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4255
68.0k
    ParamsTarget.push_back(
4256
68.0k
        std::make_pair(StringRef(), QualType())); // __context with shared vars;
4257
    // Start a captured region for 'target' with no implicit parameters.
4258
68.0k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4259
68.0k
                             ParamsTarget,
4260
68.0k
                             /*OpenMPCaptureLevel=*/1);
4261
68.0k
    Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
4262
68.0k
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4263
68.0k
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4264
68.0k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4265
68.0k
    };
4266
    // Start a captured region for 'teams' or 'parallel'.  Both regions have
4267
    // the same implicit parameters.
4268
68.0k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4269
68.0k
                             ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4270
68.0k
    break;
4271
55.7k
  }
4272
81.5k
  case OMPD_target:
4273
93.7k
  case OMPD_target_simd: {
4274
93.7k
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4275
93.7k
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4276
93.7k
    QualType KmpInt32PtrTy =
4277
93.7k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4278
93.7k
    QualType Args[] = {VoidPtrTy};
4279
93.7k
    FunctionProtoType::ExtProtoInfo EPI;
4280
93.7k
    EPI.Variadic = true;
4281
93.7k
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4282
93.7k
    Sema::CapturedParamNameType Params[] = {
4283
93.7k
        std::make_pair(".global_tid.", KmpInt32Ty),
4284
93.7k
        std::make_pair(".part_id.", KmpInt32PtrTy),
4285
93.7k
        std::make_pair(".privates.", VoidPtrTy),
4286
93.7k
        std::make_pair(
4287
93.7k
            ".copy_fn.",
4288
93.7k
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4289
93.7k
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4290
93.7k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4291
93.7k
    };
4292
93.7k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4293
93.7k
                             Params, /*OpenMPCaptureLevel=*/0);
4294
    // Mark this captured region as inlined, because we don't use outlined
4295
    // function directly.
4296
93.7k
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4297
93.7k
        AlwaysInlineAttr::CreateImplicit(
4298
93.7k
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4299
93.7k
    SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4300
93.7k
    if (getLangOpts().OpenMPIsTargetDevice)
4301
1.00k
      ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4302
93.7k
    ParamsTarget.push_back(
4303
93.7k
        std::make_pair(StringRef(), QualType())); // __context with shared vars;
4304
93.7k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4305
93.7k
                             ParamsTarget,
4306
93.7k
                             /*OpenMPCaptureLevel=*/1);
4307
93.7k
    break;
4308
81.5k
  }
4309
20.5k
  case OMPD_atomic:
4310
23.1k
  case OMPD_critical:
4311
25.1k
  case OMPD_section:
4312
27.2k
  case OMPD_master:
4313
27.4k
  case OMPD_masked:
4314
27.4k
  case OMPD_tile:
4315
27.5k
  case OMPD_unroll:
4316
27.5k
    break;
4317
91
  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
9.79k
  case OMPD_simd:
4321
21.7k
  case OMPD_for:
4322
31.1k
  case OMPD_for_simd:
4323
38.2k
  case OMPD_sections:
4324
41.2k
  case OMPD_single:
4325
51.0k
  case OMPD_taskgroup:
4326
53.8k
  case OMPD_distribute:
4327
61.9k
  case OMPD_distribute_simd:
4328
64.0k
  case OMPD_ordered:
4329
65.6k
  case OMPD_scope:
4330
71.6k
  case OMPD_target_data:
4331
71.7k
  case OMPD_dispatch: {
4332
71.7k
    Sema::CapturedParamNameType Params[] = {
4333
71.7k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4334
71.7k
    };
4335
71.7k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4336
71.7k
                             Params);
4337
71.7k
    break;
4338
71.6k
  }
4339
6.03k
  case OMPD_task: {
4340
6.03k
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4341
6.03k
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4342
6.03k
    QualType KmpInt32PtrTy =
4343
6.03k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4344
6.03k
    QualType Args[] = {VoidPtrTy};
4345
6.03k
    FunctionProtoType::ExtProtoInfo EPI;
4346
6.03k
    EPI.Variadic = true;
4347
6.03k
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4348
6.03k
    Sema::CapturedParamNameType Params[] = {
4349
6.03k
        std::make_pair(".global_tid.", KmpInt32Ty),
4350
6.03k
        std::make_pair(".part_id.", KmpInt32PtrTy),
4351
6.03k
        std::make_pair(".privates.", VoidPtrTy),
4352
6.03k
        std::make_pair(
4353
6.03k
            ".copy_fn.",
4354
6.03k
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4355
6.03k
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4356
6.03k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4357
6.03k
    };
4358
6.03k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4359
6.03k
                             Params);
4360
    // Mark this captured region as inlined, because we don't use outlined
4361
    // function directly.
4362
6.03k
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4363
6.03k
        AlwaysInlineAttr::CreateImplicit(
4364
6.03k
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4365
6.03k
    break;
4366
71.6k
  }
4367
10.1k
  case OMPD_taskloop:
4368
18.9k
  case OMPD_taskloop_simd:
4369
26.2k
  case OMPD_master_taskloop:
4370
30.2k
  case OMPD_masked_taskloop:
4371
37.8k
  case OMPD_masked_taskloop_simd:
4372
46.4k
  case OMPD_master_taskloop_simd: {
4373
46.4k
    QualType KmpInt32Ty =
4374
46.4k
        Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4375
46.4k
            .withConst();
4376
46.4k
    QualType KmpUInt64Ty =
4377
46.4k
        Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4378
46.4k
            .withConst();
4379
46.4k
    QualType KmpInt64Ty =
4380
46.4k
        Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4381
46.4k
            .withConst();
4382
46.4k
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4383
46.4k
    QualType KmpInt32PtrTy =
4384
46.4k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4385
46.4k
    QualType Args[] = {VoidPtrTy};
4386
46.4k
    FunctionProtoType::ExtProtoInfo EPI;
4387
46.4k
    EPI.Variadic = true;
4388
46.4k
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4389
46.4k
    Sema::CapturedParamNameType Params[] = {
4390
46.4k
        std::make_pair(".global_tid.", KmpInt32Ty),
4391
46.4k
        std::make_pair(".part_id.", KmpInt32PtrTy),
4392
46.4k
        std::make_pair(".privates.", VoidPtrTy),
4393
46.4k
        std::make_pair(
4394
46.4k
            ".copy_fn.",
4395
46.4k
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4396
46.4k
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4397
46.4k
        std::make_pair(".lb.", KmpUInt64Ty),
4398
46.4k
        std::make_pair(".ub.", KmpUInt64Ty),
4399
46.4k
        std::make_pair(".st.", KmpInt64Ty),
4400
46.4k
        std::make_pair(".liter.", KmpInt32Ty),
4401
46.4k
        std::make_pair(".reductions.", VoidPtrTy),
4402
46.4k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4403
46.4k
    };
4404
46.4k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4405
46.4k
                             Params);
4406
    // Mark this captured region as inlined, because we don't use outlined
4407
    // function directly.
4408
46.4k
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4409
46.4k
        AlwaysInlineAttr::CreateImplicit(
4410
46.4k
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4411
46.4k
    break;
4412
37.8k
  }
4413
4.72k
  case OMPD_parallel_masked_taskloop:
4414
10.5k
  case OMPD_parallel_masked_taskloop_simd:
4415
15.5k
  case OMPD_parallel_master_taskloop:
4416
21.8k
  case OMPD_parallel_master_taskloop_simd: {
4417
21.8k
    QualType KmpInt32Ty =
4418
21.8k
        Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4419
21.8k
            .withConst();
4420
21.8k
    QualType KmpUInt64Ty =
4421
21.8k
        Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4422
21.8k
            .withConst();
4423
21.8k
    QualType KmpInt64Ty =
4424
21.8k
        Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4425
21.8k
            .withConst();
4426
21.8k
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4427
21.8k
    QualType KmpInt32PtrTy =
4428
21.8k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4429
21.8k
    Sema::CapturedParamNameType ParamsParallel[] = {
4430
21.8k
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4431
21.8k
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4432
21.8k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4433
21.8k
    };
4434
    // Start a captured region for 'parallel'.
4435
21.8k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4436
21.8k
                             ParamsParallel, /*OpenMPCaptureLevel=*/0);
4437
21.8k
    QualType Args[] = {VoidPtrTy};
4438
21.8k
    FunctionProtoType::ExtProtoInfo EPI;
4439
21.8k
    EPI.Variadic = true;
4440
21.8k
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4441
21.8k
    Sema::CapturedParamNameType Params[] = {
4442
21.8k
        std::make_pair(".global_tid.", KmpInt32Ty),
4443
21.8k
        std::make_pair(".part_id.", KmpInt32PtrTy),
4444
21.8k
        std::make_pair(".privates.", VoidPtrTy),
4445
21.8k
        std::make_pair(
4446
21.8k
            ".copy_fn.",
4447
21.8k
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4448
21.8k
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4449
21.8k
        std::make_pair(".lb.", KmpUInt64Ty),
4450
21.8k
        std::make_pair(".ub.", KmpUInt64Ty),
4451
21.8k
        std::make_pair(".st.", KmpInt64Ty),
4452
21.8k
        std::make_pair(".liter.", KmpInt32Ty),
4453
21.8k
        std::make_pair(".reductions.", VoidPtrTy),
4454
21.8k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4455
21.8k
    };
4456
21.8k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4457
21.8k
                             Params, /*OpenMPCaptureLevel=*/1);
4458
    // Mark this captured region as inlined, because we don't use outlined
4459
    // function directly.
4460
21.8k
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4461
21.8k
        AlwaysInlineAttr::CreateImplicit(
4462
21.8k
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4463
21.8k
    break;
4464
15.5k
  }
4465
9.63k
  case OMPD_distribute_parallel_for_simd:
4466
17.3k
  case OMPD_distribute_parallel_for: {
4467
17.3k
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4468
17.3k
    QualType KmpInt32PtrTy =
4469
17.3k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4470
17.3k
    Sema::CapturedParamNameType Params[] = {
4471
17.3k
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4472
17.3k
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4473
17.3k
        std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4474
17.3k
        std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4475
17.3k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4476
17.3k
    };
4477
17.3k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4478
17.3k
                             Params);
4479
17.3k
    break;
4480
9.63k
  }
4481
523
  case OMPD_target_teams_loop:
4482
10.9k
  case OMPD_target_teams_distribute_parallel_for:
4483
23.9k
  case OMPD_target_teams_distribute_parallel_for_simd: {
4484
23.9k
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4485
23.9k
    QualType KmpInt32PtrTy =
4486
23.9k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4487
23.9k
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4488
4489
23.9k
    QualType Args[] = {VoidPtrTy};
4490
23.9k
    FunctionProtoType::ExtProtoInfo EPI;
4491
23.9k
    EPI.Variadic = true;
4492
23.9k
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4493
23.9k
    Sema::CapturedParamNameType Params[] = {
4494
23.9k
        std::make_pair(".global_tid.", KmpInt32Ty),
4495
23.9k
        std::make_pair(".part_id.", KmpInt32PtrTy),
4496
23.9k
        std::make_pair(".privates.", VoidPtrTy),
4497
23.9k
        std::make_pair(
4498
23.9k
            ".copy_fn.",
4499
23.9k
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4500
23.9k
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4501
23.9k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4502
23.9k
    };
4503
23.9k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4504
23.9k
                             Params, /*OpenMPCaptureLevel=*/0);
4505
    // Mark this captured region as inlined, because we don't use outlined
4506
    // function directly.
4507
23.9k
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4508
23.9k
        AlwaysInlineAttr::CreateImplicit(
4509
23.9k
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4510
23.9k
    SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4511
23.9k
    if (getLangOpts().OpenMPIsTargetDevice)
4512
475
      ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4513
23.9k
    ParamsTarget.push_back(
4514
23.9k
        std::make_pair(StringRef(), QualType())); // __context with shared vars;
4515
    // Start a captured region for 'target' with no implicit parameters.
4516
23.9k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4517
23.9k
                             ParamsTarget, /*OpenMPCaptureLevel=*/1);
4518
4519
23.9k
    Sema::CapturedParamNameType ParamsTeams[] = {
4520
23.9k
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4521
23.9k
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4522
23.9k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4523
23.9k
    };
4524
    // Start a captured region for 'target' with no implicit parameters.
4525
23.9k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4526
23.9k
                             ParamsTeams, /*OpenMPCaptureLevel=*/2);
4527
4528
23.9k
    Sema::CapturedParamNameType ParamsParallel[] = {
4529
23.9k
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4530
23.9k
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4531
23.9k
        std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4532
23.9k
        std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4533
23.9k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4534
23.9k
    };
4535
    // Start a captured region for 'teams' or 'parallel'.  Both regions have
4536
    // the same implicit parameters.
4537
23.9k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4538
23.9k
                             ParamsParallel, /*OpenMPCaptureLevel=*/3);
4539
23.9k
    break;
4540
10.9k
  }
4541
4542
211
  case OMPD_teams_loop:
4543
7.99k
  case OMPD_teams_distribute_parallel_for:
4544
16.9k
  case OMPD_teams_distribute_parallel_for_simd: {
4545
16.9k
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4546
16.9k
    QualType KmpInt32PtrTy =
4547
16.9k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4548
4549
16.9k
    Sema::CapturedParamNameType ParamsTeams[] = {
4550
16.9k
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4551
16.9k
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4552
16.9k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4553
16.9k
    };
4554
    // Start a captured region for 'target' with no implicit parameters.
4555
16.9k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4556
16.9k
                             ParamsTeams, /*OpenMPCaptureLevel=*/0);
4557
4558
16.9k
    Sema::CapturedParamNameType ParamsParallel[] = {
4559
16.9k
        std::make_pair(".global_tid.", KmpInt32PtrTy),
4560
16.9k
        std::make_pair(".bound_tid.", KmpInt32PtrTy),
4561
16.9k
        std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4562
16.9k
        std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4563
16.9k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4564
16.9k
    };
4565
    // Start a captured region for 'teams' or 'parallel'.  Both regions have
4566
    // the same implicit parameters.
4567
16.9k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4568
16.9k
                             ParamsParallel, /*OpenMPCaptureLevel=*/1);
4569
16.9k
    break;
4570
7.99k
  }
4571
4.78k
  case OMPD_target_update:
4572
7.59k
  case OMPD_target_enter_data:
4573
10.3k
  case OMPD_target_exit_data: {
4574
10.3k
    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4575
10.3k
    QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4576
10.3k
    QualType KmpInt32PtrTy =
4577
10.3k
        Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4578
10.3k
    QualType Args[] = {VoidPtrTy};
4579
10.3k
    FunctionProtoType::ExtProtoInfo EPI;
4580
10.3k
    EPI.Variadic = true;
4581
10.3k
    QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4582
10.3k
    Sema::CapturedParamNameType Params[] = {
4583
10.3k
        std::make_pair(".global_tid.", KmpInt32Ty),
4584
10.3k
        std::make_pair(".part_id.", KmpInt32PtrTy),
4585
10.3k
        std::make_pair(".privates.", VoidPtrTy),
4586
10.3k
        std::make_pair(
4587
10.3k
            ".copy_fn.",
4588
10.3k
            Context.getPointerType(CopyFnType).withConst().withRestrict()),
4589
10.3k
        std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4590
10.3k
        std::make_pair(StringRef(), QualType()) // __context with shared vars
4591
10.3k
    };
4592
10.3k
    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4593
10.3k
                             Params);
4594
    // Mark this captured region as inlined, because we don't use outlined
4595
    // function directly.
4596
10.3k
    getCurCapturedRegion()->TheCapturedDecl->addAttr(
4597
10.3k
        AlwaysInlineAttr::CreateImplicit(
4598
10.3k
            Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4599
10.3k
    break;
4600
7.59k
  }
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
534k
  }
4627
534k
  DSAStack->setContext(CurContext);
4628
534k
  handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4629
534k
}
4630
4631
316
int Sema::getNumberOfConstructScopes(unsigned Level) const {
4632
316
  return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4633
316
}
4634
4635
660k
int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4636
660k
  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4637
660k
  getOpenMPCaptureRegions(CaptureRegions, DKind);
4638
660k
  return CaptureRegions.size();
4639
660k
}
4640
4641
static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4642
                                             Expr *CaptureExpr, bool WithInit,
4643
                                             DeclContext *CurContext,
4644
83.3k
                                             bool AsExpression) {
4645
83.3k
  assert(CaptureExpr);
4646
83.3k
  ASTContext &C = S.getASTContext();
4647
83.3k
  Expr *Init = AsExpression ? 
CaptureExpr79.1k
:
CaptureExpr->IgnoreImpCasts()4.15k
;
4648
83.3k
  QualType Ty = Init->getType();
4649
83.3k
  if (CaptureExpr->getObjectKind() == OK_Ordinary && 
CaptureExpr->isGLValue()82.9k
) {
4650
5.60k
    if (S.getLangOpts().CPlusPlus) {
4651
5.60k
      Ty = C.getLValueReferenceType(Ty);
4652
5.60k
    } 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
5.60k
    WithInit = true;
4661
5.60k
  }
4662
83.3k
  auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
4663
83.3k
                                          CaptureExpr->getBeginLoc());
4664
83.3k
  if (!WithInit)
4665
304
    CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4666
83.3k
  CurContext->addHiddenDecl(CED);
4667
83.3k
  Sema::TentativeAnalysisScope Trap(S);
4668
83.3k
  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4669
83.3k
  return CED;
4670
83.3k
}
4671
4672
static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4673
4.36k
                                 bool WithInit) {
4674
4.36k
  OMPCapturedExprDecl *CD;
4675
4.36k
  if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4676
224
    CD = cast<OMPCapturedExprDecl>(VD);
4677
4.13k
  else
4678
4.13k
    CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4679
4.13k
                          S.CurContext,
4680
4.13k
                          /*AsExpression=*/false);
4681
4.36k
  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4682
4.36k
                          CaptureExpr->getExprLoc());
4683
4.36k
}
4684
4685
static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref,
4686
158k
                               StringRef Name) {
4687
158k
  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4688
158k
  if (!Ref) {
4689
79.1k
    OMPCapturedExprDecl *CD = buildCaptureDecl(
4690
79.1k
        S, &S.getASTContext().Idents.get(Name), CaptureExpr,
4691
79.1k
        /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
4692
79.1k
    Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4693
79.1k
                           CaptureExpr->getExprLoc());
4694
79.1k
  }
4695
158k
  ExprResult Res = Ref;
4696
158k
  if (!S.getLangOpts().CPlusPlus &&
4697
158k
      
CaptureExpr->getObjectKind() == OK_Ordinary1.58k
&&
CaptureExpr->isGLValue()1.58k
&&
4698
158k
      
Ref->getType()->isPointerType()0
) {
4699
0
    Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4700
0
    if (!Res.isUsable())
4701
0
      return ExprError();
4702
0
  }
4703
158k
  return S.DefaultLvalueConversion(Res.get());
4704
158k
}
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
507k
      : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4725
507k
  ~CaptureRegionUnwinderRAII() {
4726
507k
    if (ErrorFound) {
4727
21.2k
      int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4728
50.6k
      while (--ThisCaptureLevel >= 0)
4729
29.3k
        S.ActOnCapturedRegionError();
4730
21.2k
    }
4731
507k
  }
4732
};
4733
} // namespace
4734
4735
1.74M
void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4736
  // Capture variables captured by reference in lambdas for target-based
4737
  // directives.
4738
1.74M
  if (!CurContext->isDependentContext() &&
4739
1.74M
      (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4740
1.74M
       isOpenMPTargetDataManagementDirective(
4741
1.10M
           DSAStack->getCurrentDirective()))) {
4742
667k
    QualType Type = V->getType();
4743
667k
    if (const auto *RD = Type.getCanonicalType()
4744
667k
                             .getNonReferenceType()
4745
667k
                             ->getAsCXXRecordDecl()) {
4746
57.8k
      bool SavedForceCaptureByReferenceInTargetExecutable =
4747
57.8k
          DSAStack->isForceCaptureByReferenceInTargetExecutable();
4748
57.8k
      DSAStack->setForceCaptureByReferenceInTargetExecutable(
4749
57.8k
          /*V=*/true);
4750
57.8k
      if (RD->isLambda()) {
4751
120
        llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4752
120
        FieldDecl *ThisCapture;
4753
120
        RD->getCaptureFields(Captures, ThisCapture);
4754
184
        for (const LambdaCapture &LC : RD->captures()) {
4755
184
          if (LC.getCaptureKind() == LCK_ByRef) {
4756
12
            VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4757
12
            DeclContext *VDC = VD->getDeclContext();
4758
12
            if (!VDC->Encloses(CurContext))
4759
0
              continue;
4760
12
            MarkVariableReferenced(LC.getLocation(), VD);
4761
172
          } 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
184
        }
4768
120
      }
4769
57.8k
      DSAStack->setForceCaptureByReferenceInTargetExecutable(
4770
57.8k
          SavedForceCaptureByReferenceInTargetExecutable);
4771
57.8k
    }
4772
667k
  }
4773
1.74M
}
4774
4775
static bool checkOrderedOrderSpecified(Sema &S,
4776
486k
                                       const ArrayRef<OMPClause *> Clauses) {
4777
486k
  const OMPOrderedClause *Ordered = nullptr;
4778
486k
  const OMPOrderClause *Order = nullptr;
4779
4780
486k
  for (const OMPClause *Clause : Clauses) {
4781
223k
    if (Clause->getClauseKind() == OMPC_ordered)
4782
1.33k
      Ordered = cast<OMPOrderedClause>(Clause);
4783
222k
    else if (Clause->getClauseKind() == OMPC_order) {
4784
663
      Order = cast<OMPOrderClause>(Clause);
4785
663
      if (Order->getKind() != OMPC_ORDER_concurrent)
4786
0
        Order = nullptr;
4787
663
    }
4788
223k
    if (Ordered && 
Order2.10k
)
4789
4
      break;
4790
223k
  }
4791
4792
486k
  if (Ordered && 
Order1.33k
) {
4793
4
    S.Diag(Order->getKindKwLoc(),
4794
4
           diag::err_omp_simple_clause_incompatible_with_ordered)
4795
4
        << getOpenMPClauseName(OMPC_order)
4796
4
        << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4797
4
        << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4798
4
    S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4799
4
        << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4800
4
    return true;
4801
4
  }
4802
486k
  return false;
4803
486k
}
4804
4805
StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4806
534k
                                      ArrayRef<OMPClause *> Clauses) {
4807
534k
  handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4808
534k
                                     /* ScopeEntry */ false);
4809
534k
  if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4810
534k
      
DSAStack514k
->getCurrentDirective() == OMPD_critical514k
||
4811
534k
      
DSAStack511k
->getCurrentDirective() == OMPD_section511k
||
4812
534k
      
DSAStack509k
->getCurrentDirective() == OMPD_master509k
||
4813
534k
      
DSAStack507k
->getCurrentDirective() == OMPD_masked507k
)
4814
27.4k
    return S;
4815
4816
507k
  bool ErrorFound = false;
4817
507k
  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4818
507k
      *this, ErrorFound, DSAStack->getCurrentDirective());
4819
507k
  if (!S.isUsable()) {
4820
21.1k
    ErrorFound = true;
4821
21.1k
    return StmtError();
4822
21.1k
  }
4823
4824
486k
  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4825
486k
  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4826
486k
  OMPOrderedClause *OC = nullptr;
4827
486k
  OMPScheduleClause *SC = nullptr;
4828
486k
  SmallVector<const OMPLinearClause *, 4> LCs;
4829
486k
  SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4830
  // This is required for proper codegen.
4831
486k
  for (OMPClause *Clause : Clauses) {
4832
223k
    if (!LangOpts.OpenMPSimd &&
4833
223k
        
(117k
isOpenMPTaskingDirective(117k
DSAStack117k
->getCurrentDirective()) ||
4834
117k
         
DSAStack98.9k
->getCurrentDirective() == OMPD_target98.9k
) &&
4835
223k
        
Clause->getClauseKind() == OMPC_in_reduction28.3k
) {
4836
      // Capture taskgroup task_reduction descriptors inside the tasking regions
4837
      // with the corresponding in_reduction items.
4838
2.81k
      auto *IRC = cast<OMPInReductionClause>(Clause);
4839
2.81k
      for (Expr *E : IRC->taskgroup_descriptors())
4840
3.27k
        if (E)
4841
1.57k
          MarkDeclarationsReferencedInExpr(E);
4842
2.81k
    }
4843
223k
    if (isOpenMPPrivate(Clause->getClauseKind()) ||
4844
223k
        
Clause->getClauseKind() == OMPC_copyprivate118k
||
4845
223k
        
(118k
getLangOpts().OpenMPUseTLS118k
&&
4846
118k
         
getASTContext().getTargetInfo().isTLSSupported()63.7k
&&
4847
118k
         
Clause->getClauseKind() == OMPC_copyin62.2k
)) {
4848
105k
      DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4849
      // Mark all variables in private list clauses as used in inner region.
4850
133k
      for (Stmt *VarRef : Clause->children()) {
4851
133k
        if (auto *E = cast_or_null<Expr>(VarRef)) {
4852
133k
          MarkDeclarationsReferencedInExpr(E);
4853
133k
        }
4854
133k
      }
4855
105k
      DSAStack->setForceVarCapturing(/*V=*/false);
4856
118k
    } else if (isOpenMPLoopTransformationDirective(
4857
118k
                   DSAStack->getCurrentDirective())) {
4858
160
      assert(CaptureRegions.empty() &&
4859
160
             "No captured regions in loop transformation directives.");
4860
117k
    } else if (CaptureRegions.size() > 1 ||
4861
117k
               
CaptureRegions.back() != OMPD_unknown53.3k
) {
4862
103k
      if (auto *C = OMPClauseWithPreInit::get(Clause))
4863
28.2k
        PICs.push_back(C);
4864
103k
      if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4865
0
        if (Expr *E = C->getPostUpdateExpr())
4866
0
          MarkDeclarationsReferencedInExpr(E);
4867
0
      }
4868
103k
    }
4869
223k
    if (Clause->getClauseKind() == OMPC_schedule)
4870
3.90k
      SC = cast<OMPScheduleClause>(Clause);
4871
219k
    else if (Clause->getClauseKind() == OMPC_ordered)
4872
1.33k
      OC = cast<OMPOrderedClause>(Clause);
4873
218k
    else if (Clause->getClauseKind() == OMPC_linear)
4874
4.87k
      LCs.push_back(cast<OMPLinearClause>(Clause));
4875
223k
  }
4876
  // Capture allocator expressions if used.
4877
486k
  for (Expr *E : DSAStack->getInnerAllocators())
4878
2.10k
    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
486k
  if (SC &&
4883
486k
      
(3.90k
SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic3.90k
||
4884
3.90k
       SC->getSecondScheduleModifier() ==
4885
3.66k
           OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4886
486k
      
OC249
) {
4887
8
    Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4888
8
             ? SC->getFirstScheduleModifierLoc()
4889
8
             : 
SC->getSecondScheduleModifierLoc()0
,
4890
8
         diag::err_omp_simple_clause_incompatible_with_ordered)
4891
8
        << getOpenMPClauseName(OMPC_schedule)
4892
8
        << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4893
8
                                         OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4894
8
        << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4895
8
    ErrorFound = true;
4896
8
  }
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
486k
  if (checkOrderedOrderSpecified(*this, Clauses))
4901
4
    ErrorFound = true;
4902
486k
  if (!LCs.empty() && 
OC4.78k
&&
OC->getNumForLoops()72
) {
4903
8
    for (const OMPLinearClause *C : LCs) {
4904
8
      Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4905
8
          << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4906
8
    }
4907
8
    ErrorFound = true;
4908
8
  }
4909
486k
  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4910
486k
      
isOpenMPSimdDirective(137k
DSAStack137k
->getCurrentDirective()) &&
OC61.5k
&&
4911
486k
      
OC->getNumForLoops()279
) {
4912
76
    Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4913
76
        << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4914
76
    ErrorFound = true;
4915
76
  }
4916
486k
  if (ErrorFound) {
4917
96
    return StmtError();
4918
96
  }
4919
486k
  StmtResult SR = S;
4920
486k
  unsigned CompletedRegions = 0;
4921
818k
  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
818k
    if (ThisCaptureRegion != OMPD_unknown) {
4926
747k
      for (const clang::OMPClauseWithPreInit *C : PICs) {
4927
60.6k
        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
60.6k
        if (CaptureRegion == ThisCaptureRegion ||
4934
60.6k
            
CaptureRegion == OMPD_unknown50.7k
) {
4935
45.0k
          if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4936
8.13k
            for (Decl *D : DS->decls())
4937
8.13k
              MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4938
8.13k
          }
4939
45.0k
        }
4940
60.6k
      }
4941
747k
    }
4942
818k
    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
177k
      for (OMPClause *C : Clauses) {
4946
78.8k
        if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4947
870
          for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4948
463
               ++I) {
4949
463
            OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4950
463
            if (Expr *E = D.AllocatorTraits)
4951
46
              MarkDeclarationsReferencedInExpr(E);
4952
463
          }
4953
407
          continue;
4954
407
        }
4955
78.8k
      }
4956
177k
    }
4957
818k
    if (ThisCaptureRegion == OMPD_parallel) {
4958
      // Capture temp arrays for inscan reductions and locals in aligned
4959
      // clauses.
4960
190k
      for (OMPClause *C : Clauses) {
4961
96.5k
        if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4962
27.9k
          if (RC->getModifier() != OMPC_REDUCTION_inscan)
4963
27.7k
            continue;
4964
121
          for (Expr *E : RC->copy_array_temps())
4965
221
            MarkDeclarationsReferencedInExpr(E);
4966
121
        }
4967
68.8k
        if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4968
802
          for (Expr *E : AC->varlists())
4969
862
            MarkDeclarationsReferencedInExpr(E);
4970
802
        }
4971
68.8k
      }
4972
190k
    }
4973
818k
    if (++CompletedRegions == CaptureRegions.size())
4974
485k
      DSAStack->setBodyComplete();
4975
818k
    SR = ActOnCapturedRegionEnd(SR.get());
4976
818k
  }
4977
486k
  return SR;
4978
486k
}
4979
4980
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4981
                              OpenMPDirectiveKind CancelRegion,
4982
502k
                              SourceLocation StartLoc) {
4983
  // CancelRegion is only needed for cancel and cancellation_point.
4984
502k
  if (CurrentRegion != OMPD_cancel && 
CurrentRegion != OMPD_cancellation_point501k
)
4985
500k
    return false;
4986
4987
1.17k
  if (CancelRegion == OMPD_parallel || 
CancelRegion == OMPD_for797
||
4988
1.17k
      
CancelRegion == OMPD_sections552
||
CancelRegion == OMPD_taskgroup400
)
4989
1.15k
    return false;
4990
4991
20
  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4992
20
      << getOpenMPDirectiveName(CancelRegion);
4993
20
  return true;
4994
1.17k
}
4995
4996
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4997
                                  OpenMPDirectiveKind CurrentRegion,
4998
                                  const DeclarationNameInfo &CurrentName,
4999
                                  OpenMPDirectiveKind CancelRegion,
5000
                                  OpenMPBindClauseKind BindKind,
5001
502k
                                  SourceLocation StartLoc) {
5002
502k
  if (Stack->getCurScope()) {
5003
353k
    OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
5004
353k
    OpenMPDirectiveKind OffendingRegion = ParentRegion;
5005
353k
    bool NestingProhibited = false;
5006
353k
    bool CloseNesting = true;
5007
353k
    bool OrphanSeen = false;
5008
353k
    enum {
5009
353k
      NoRecommend,
5010
353k
      ShouldBeInParallelRegion,
5011
353k
      ShouldBeInOrderedRegion,
5012
353k
      ShouldBeInTargetRegion,
5013
353k
      ShouldBeInTeamsRegion,
5014
353k
      ShouldBeInLoopSimdRegion,
5015
353k
    } Recommend = NoRecommend;
5016
353k
    if (SemaRef.LangOpts.OpenMP >= 51 && 
Stack->isParentOrderConcurrent()241k
&&
5017
353k
        
CurrentRegion != OMPD_simd8
&&
CurrentRegion != OMPD_loop8
&&
5018
353k
        
CurrentRegion != OMPD_parallel6
&&
5019
353k
        
!isOpenMPCombinedParallelADirective(CurrentRegion)6
) {
5020
6
      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
5021
6
          << getOpenMPDirectiveName(CurrentRegion);
5022
6
      return true;
5023
6
    }
5024
353k
    if (isOpenMPSimdDirective(ParentRegion) &&
5025
353k
        
(7.64k
(7.64k
SemaRef.LangOpts.OpenMP <= 457.64k
&&
CurrentRegion != OMPD_ordered3.27k
) ||
5026
7.64k
         
(4.48k
SemaRef.LangOpts.OpenMP >= 504.48k
&&
CurrentRegion != OMPD_ordered4.37k
&&
5027
4.48k
          
CurrentRegion != OMPD_simd4.07k
&&
CurrentRegion != OMPD_atomic3.97k
&&
5028
6.83k
          
CurrentRegion != OMPD_scan3.85k
))) {
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
6.83k
      SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
5042
6.83k
                                 ? 
diag::err_omp_prohibited_region_simd6.75k
5043
6.83k
                                 : 
diag::warn_omp_nesting_simd76
)
5044
6.83k
          << (SemaRef.LangOpts.OpenMP >= 50 ? 
13.67k
:
03.16k
);
5045
6.83k
      return CurrentRegion != OMPD_simd;
5046
6.83k
    }
5047
346k
    if (ParentRegion == OMPD_atomic) {
5048
      // OpenMP [2.16, Nesting of Regions]
5049
      // OpenMP constructs may not be nested inside an atomic region.
5050
801
      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5051
801
      return true;
5052
801
    }
5053
345k
    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
1.35k
      if (ParentRegion != OMPD_sections &&
5059
1.35k
          
ParentRegion != OMPD_parallel_sections449
) {
5060
351
        SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5061
351
            << (ParentRegion != OMPD_unknown)
5062
351
            << getOpenMPDirectiveName(ParentRegion);
5063
351
        return true;
5064
351
      }
5065
1.00k
      return false;
5066
1.35k
    }
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
344k
    if (ParentRegion == OMPD_unknown &&
5071
344k
        
!isOpenMPNestingTeamsDirective(CurrentRegion)232k
&&
5072
344k
        
CurrentRegion != OMPD_cancellation_point231k
&&
5073
344k
        
CurrentRegion != OMPD_cancel231k
&&
CurrentRegion != OMPD_scan231k
)
5074
231k
      return false;
5075
112k
    if (CurrentRegion == OMPD_cancellation_point ||
5076
112k
        
CurrentRegion == OMPD_cancel112k
) {
5077
      // OpenMP [2.16, Nesting of Regions]
5078
      // A cancellation point construct for which construct-type-clause is
5079
      // taskgroup must be nested inside a task construct. A cancellation
5080
      // point construct for which construct-type-clause is not taskgroup must
5081
      // be closely nested inside an OpenMP construct that matches the type
5082
      // specified in construct-type-clause.
5083
      // A cancel construct for which construct-type-clause is taskgroup must be
5084
      // nested inside a task construct. A cancel construct for which
5085
      // construct-type-clause is not taskgroup must be closely nested inside an
5086
      // OpenMP construct that matches the type specified in
5087
      // construct-type-clause.
5088
941
      NestingProhibited =
5089
941
          !((CancelRegion == OMPD_parallel &&
5090
941
             
(322
ParentRegion == OMPD_parallel322
||
5091
322
              
ParentRegion == OMPD_target_parallel134
)) ||
5092
941
            
(701
CancelRegion == OMPD_for701
&&
5093
701
             
(229
ParentRegion == OMPD_for229
||
ParentRegion == OMPD_parallel_for193
||
5094
229
              
ParentRegion == OMPD_target_parallel_for173
||
5095
229
              
ParentRegion == OMPD_distribute_parallel_for93
||
5096
229
              
ParentRegion == OMPD_teams_distribute_parallel_for71
||
5097
229
              
ParentRegion == OMPD_target_teams_distribute_parallel_for57
)) ||
5098
941
            
(500
CancelRegion == OMPD_taskgroup500
&&
5099
500
             
(238
ParentRegion == OMPD_task238
||
5100
238
              
(202
SemaRef.getLangOpts().OpenMP >= 50202
&&
5101
202
               
(178
ParentRegion == OMPD_taskloop178
||
5102
178
                
ParentRegion == OMPD_master_taskloop128
||
5103
178
                
ParentRegion == OMPD_masked_taskloop94
||
5104
178
                
ParentRegion == OMPD_parallel_masked_taskloop78
||
5105
178
                
ParentRegion == OMPD_parallel_master_taskloop62
)))) ||
5106
941
            
(314
CancelRegion == OMPD_sections314
&&
5107
314
             
(152
ParentRegion == OMPD_section152
||
ParentRegion == OMPD_sections116
||
5108
152
              
ParentRegion == OMPD_parallel_sections68
)));
5109
941
      OrphanSeen = ParentRegion == OMPD_unknown;
5110
111k
    } else if (CurrentRegion == OMPD_master || 
CurrentRegion == OMPD_masked111k
) {
5111
      // OpenMP 5.1 [2.22, Nesting of Regions]
5112
      // A masked region may not be closely nested inside a worksharing, loop,
5113
      // atomic, task, or taskloop region.
5114
627
      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
5115
627
                          
isOpenMPGenericLoopDirective(ParentRegion)419
||
5116
627
                          
isOpenMPTaskingDirective(ParentRegion)418
;
5117
111k
    } else if (CurrentRegion == OMPD_critical && 
CurrentName.getName()670
) {
5118
      // OpenMP [2.16, Nesting of Regions]
5119
      // A critical region may not be nested (closely or otherwise) inside a
5120
      // critical region with the same name. Note that this restriction is not
5121
      // sufficient to prevent deadlock.
5122
106
      SourceLocation PreviousCriticalLoc;
5123
106
      bool DeadLock = Stack->hasDirective(
5124
106
          [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
5125
106
                                              const DeclarationNameInfo &DNI,
5126
230
                                              SourceLocation Loc) {
5127
230
            if (K == OMPD_critical && 
DNI.getName() == CurrentName.getName()169
) {
5128
31
              PreviousCriticalLoc = Loc;
5129
31
              return true;
5130
31
            }
5131
199
            return false;
5132
230
          },
5133
106
          false /* skip top directive */);
5134
106
      if (DeadLock) {
5135
31
        SemaRef.Diag(StartLoc,
5136
31
                     diag::err_omp_prohibited_region_critical_same_name)
5137
31
            << CurrentName.getName();
5138
31
        if (PreviousCriticalLoc.isValid())
5139
31
          SemaRef.Diag(PreviousCriticalLoc,
5140
31
                       diag::note_omp_previous_critical_region);
5141
31
        return true;
5142
31
      }
5143
110k
    } else if (CurrentRegion == OMPD_barrier || 
CurrentRegion == OMPD_scope110k
) {
5144
      // OpenMP 5.1 [2.22, Nesting of Regions]
5145
      // A scope region may not be closely nested inside a worksharing, loop,
5146
      // task, taskloop, critical, ordered, atomic, or masked region.
5147
      // OpenMP 5.1 [2.22, Nesting of Regions]
5148
      // A barrier region may not be closely nested inside a worksharing, loop,
5149
      // task, taskloop, critical, ordered, atomic, or masked region.
5150
778
      NestingProhibited =
5151
778
          isOpenMPWorksharingDirective(ParentRegion) ||
5152
778
          
isOpenMPGenericLoopDirective(ParentRegion)432
||
5153
778
          
isOpenMPTaskingDirective(ParentRegion)431
||
5154
778
          
ParentRegion == OMPD_master359
||
ParentRegion == OMPD_masked323
||
5155
778
          
ParentRegion == OMPD_parallel_master323
||
5156
778
          
ParentRegion == OMPD_parallel_masked287
||
5157
778
          
ParentRegion == OMPD_critical287
||
ParentRegion == OMPD_ordered251
;
5158
110k
    } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
5159
110k
               
!isOpenMPParallelDirective(CurrentRegion)38.5k
&&
5160
110k
               
!isOpenMPTeamsDirective(CurrentRegion)11.8k
) {
5161
      // OpenMP 5.1 [2.22, Nesting of Regions]
5162
      // A loop region that binds to a parallel region or a worksharing region
5163
      // may not be closely nested inside a worksharing, loop, task, taskloop,
5164
      // critical, ordered, atomic, or masked region.
5165
11.8k
      NestingProhibited =
5166
11.8k
          isOpenMPWorksharingDirective(ParentRegion) ||
5167
11.8k
          
isOpenMPGenericLoopDirective(ParentRegion)11.0k
||
5168
11.8k
          
isOpenMPTaskingDirective(ParentRegion)11.0k
||
5169
11.8k
          
ParentRegion == OMPD_master10.9k
||
ParentRegion == OMPD_masked10.8k
||
5170
11.8k
          
ParentRegion == OMPD_parallel_master10.8k
||
5171
11.8k
          
ParentRegion == OMPD_parallel_masked10.8k
||
5172
11.8k
          
ParentRegion == OMPD_critical10.7k
||
ParentRegion == OMPD_ordered10.7k
;
5173
11.8k
      Recommend = ShouldBeInParallelRegion;
5174
98.3k
    } else if (CurrentRegion == OMPD_ordered) {
5175
      // OpenMP [2.16, Nesting of Regions]
5176
      // An ordered region may not be closely nested inside a critical,
5177
      // atomic, or explicit task region.
5178
      // An ordered region must be closely nested inside a loop region (or
5179
      // parallel loop region) with an ordered clause.
5180
      // OpenMP [2.8.1,simd Construct, Restrictions]
5181
      // An ordered construct with the simd clause is the only OpenMP construct
5182
      // that can appear in the simd region.
5183
1.57k
      NestingProhibited = ParentRegion == OMPD_critical ||
5184
1.57k
                          
isOpenMPTaskingDirective(ParentRegion)1.55k
||
5185
1.57k
                          
!(1.51k
isOpenMPSimdDirective(ParentRegion)1.51k
||
5186
1.51k
                            
Stack->isParentOrderedRegion()1.10k
);
5187
1.57k
      Recommend = ShouldBeInOrderedRegion;
5188
96.8k
    } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
5189
      // OpenMP [2.16, Nesting of Regions]
5190
      // If specified, a teams construct must be contained within a target
5191
      // construct.
5192
39.7k
      NestingProhibited =
5193
39.7k
          (SemaRef.LangOpts.OpenMP <= 45 && 
ParentRegion != OMPD_target11.5k
) ||
5194
39.7k
          
(38.7k
SemaRef.LangOpts.OpenMP >= 5038.7k
&&
ParentRegion != OMPD_unknown28.2k
&&
5195
38.7k
           
ParentRegion != OMPD_target28.0k
);
5196
39.7k
      OrphanSeen = ParentRegion == OMPD_unknown;
5197
39.7k
      Recommend = ShouldBeInTargetRegion;
5198
57.0k
    } else if (CurrentRegion == OMPD_scan) {
5199
      // OpenMP [2.16, Nesting of Regions]
5200
      // If specified, a teams construct must be contained within a target
5201
      // construct.
5202
788
      NestingProhibited =
5203
788
          SemaRef.LangOpts.OpenMP < 50 ||
5204
788
          
(588
ParentRegion != OMPD_simd588
&&
ParentRegion != OMPD_for510
&&
5205
588
           
ParentRegion != OMPD_for_simd480
&&
ParentRegion != OMPD_parallel_for456
&&
5206
588
           
ParentRegion != OMPD_parallel_for_simd333
);
5207
788
      OrphanSeen = ParentRegion == OMPD_unknown;
5208
788
      Recommend = ShouldBeInLoopSimdRegion;
5209
788
    }
5210
112k
    if (!NestingProhibited &&
5211
112k
        
!isOpenMPTargetExecutionDirective(CurrentRegion)107k
&&
5212
112k
        
!isOpenMPTargetDataManagementDirective(CurrentRegion)99.0k
&&
5213
112k
        
(96.0k
ParentRegion == OMPD_teams96.0k
||
ParentRegion == OMPD_target_teams79.8k
)) {
5214
      // OpenMP [5.1, 2.22, Nesting of Regions]
5215
      // distribute, distribute simd, distribute parallel worksharing-loop,
5216
      // distribute parallel worksharing-loop SIMD, loop, parallel regions,
5217
      // including any parallel regions arising from combined constructs,
5218
      // omp_get_num_teams() regions, and omp_get_team_num() regions are the
5219
      // only OpenMP regions that may be strictly nested inside the teams
5220
      // region.
5221
      //
5222
      // As an extension, we permit atomic within teams as well.
5223
17.0k
      NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
5224
17.0k
                          
!isOpenMPDistributeDirective(CurrentRegion)6.42k
&&
5225
17.0k
                          
CurrentRegion != OMPD_loop558
&&
5226
17.0k
                          
!(540
SemaRef.getLangOpts().OpenMPExtensions540
&&
5227
540
                            
CurrentRegion == OMPD_atomic60
);
5228
17.0k
      Recommend = ShouldBeInParallelRegion;
5229
17.0k
    }
5230
112k
    if (!NestingProhibited && 
CurrentRegion == OMPD_loop106k
) {
5231
      // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5232
      // If the bind clause is present on the loop construct and binding is
5233
      // teams then the corresponding loop region must be strictly nested inside
5234
      // a teams region.
5235
55
      NestingProhibited = BindKind == OMPC_BIND_teams &&
5236
55
                          
ParentRegion != OMPD_teams15
&&
5237
55
                          
ParentRegion != OMPD_target_teams5
;
5238
55
      Recommend = ShouldBeInTeamsRegion;
5239
55
    }
5240
112k
    if (!NestingProhibited &&
5241
112k
        
isOpenMPNestingDistributeDirective(CurrentRegion)106k
) {
5242
      // OpenMP 4.5 [2.17 Nesting of Regions]
5243
      // The region associated with the distribute construct must be strictly
5244
      // nested inside a teams region
5245
17.3k
      NestingProhibited =
5246
17.3k
          (ParentRegion != OMPD_teams && 
ParentRegion != OMPD_target_teams1.74k
);
5247
17.3k
      Recommend = ShouldBeInTeamsRegion;
5248
17.3k
    }
5249
112k
    if (!NestingProhibited &&
5250
112k
        
(105k
isOpenMPTargetExecutionDirective(CurrentRegion)105k
||
5251
105k
         
isOpenMPTargetDataManagementDirective(CurrentRegion)97.0k
)) {
5252
      // OpenMP 4.5 [2.17 Nesting of Regions]
5253
      // If a target, target update, target data, target enter data, or
5254
      // target exit data construct is encountered during execution of a
5255
      // target region, the behavior is unspecified.
5256
11.2k
      NestingProhibited = Stack->hasDirective(
5257
11.2k
          [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
5258
20.7k
                             SourceLocation) {
5259
20.7k
            if (isOpenMPTargetExecutionDirective(K)) {
5260
2.46k
              OffendingRegion = K;
5261
2.46k
              return true;
5262
2.46k
            }
5263
18.3k
            return false;
5264
20.7k
          },
5265
11.2k
          false /* don't skip top directive */);
5266
11.2k
      CloseNesting = false;
5267
11.2k
    }
5268
112k
    if (NestingProhibited) {
5269
9.78k
      if (OrphanSeen) {
5270
142
        SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5271
142
            << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5272
9.64k
      } else {
5273
9.64k
        SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5274
9.64k
            << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5275
9.64k
            << Recommend << getOpenMPDirectiveName(CurrentRegion);
5276
9.64k
      }
5277
9.78k
      return true;
5278
9.78k
    }
5279
112k
  }
5280
251k
  return false;
5281
502k
}
5282
5283
struct Kind2Unsigned {
5284
  using argument_type = OpenMPDirectiveKind;
5285
802k
  unsigned operator()(argument_type DK) { return unsigned(DK); }
5286
};
5287
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
5288
                           ArrayRef<OMPClause *> Clauses,
5289
373k
                           ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5290
373k
  bool ErrorFound = false;
5291
373k
  unsigned NamedModifiersNumber = 0;
5292
373k
  llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5293
373k
  FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5294
373k
  SmallVector<SourceLocation, 4> NameModifierLoc;
5295
373k
  for (const OMPClause *C : Clauses) {
5296
192k
    if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5297
      // At most one if clause without a directive-name-modifier can appear on
5298
      // the directive.
5299
13.4k
      OpenMPDirectiveKind CurNM = IC->getNameModifier();
5300
13.4k
      if (FoundNameModifiers[CurNM]) {
5301
444
        S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5302
444
            << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5303
444
            << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5304
444
        ErrorFound = true;
5305
13.0k
      } else if (CurNM != OMPD_unknown) {
5306
6.75k
        NameModifierLoc.push_back(IC->getNameModifierLoc());
5307
6.75k
        ++NamedModifiersNumber;
5308
6.75k
      }
5309
13.4k
      FoundNameModifiers[CurNM] = IC;
5310
13.4k
      if (CurNM == OMPD_unknown)
5311
6.48k
        continue;
5312
      // Check if the specified name modifier is allowed for the current
5313
      // directive.
5314
      // At most one if clause with the particular directive-name-modifier can
5315
      // appear on the directive.
5316
6.99k
      if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5317
292
        S.Diag(IC->getNameModifierLoc(),
5318
292
               diag::err_omp_wrong_if_directive_name_modifier)
5319
292
            << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5320
292
        ErrorFound = true;
5321
292
      }
5322
6.99k
    }
5323
192k
  }
5324
  // If any if clause on the directive includes a directive-name-modifier then
5325
  // all if clauses on the directive must include a directive-name-modifier.
5326
373k
  if (FoundNameModifiers[OMPD_unknown] && 
NamedModifiersNumber > 06.27k
) {
5327
262
    if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5328
186
      S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5329
186
             diag::err_omp_no_more_if_clause);
5330
186
    } else {
5331
76
      std::string Values;
5332
76
      std::string Sep(", ");
5333
76
      unsigned AllowedCnt = 0;
5334
76
      unsigned TotalAllowedNum =
5335
76
          AllowedNameModifiers.size() - NamedModifiersNumber;
5336
240
      for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5337
164
           ++Cnt) {
5338
164
        OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5339
164
        if (!FoundNameModifiers[NM]) {
5340
84
          Values += "'";
5341
84
          Values += getOpenMPDirectiveName(NM);
5342
84
          Values += "'";
5343
84
          if (AllowedCnt + 2 == TotalAllowedNum)
5344
12
            Values += " or ";
5345
72
          else if (AllowedCnt + 1 != TotalAllowedNum)
5346
0
            Values += Sep;
5347
84
          ++AllowedCnt;
5348
84
        }
5349
164
      }
5350
76
      S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5351
76
             diag::err_omp_unnamed_if_clause)
5352
76
          << (TotalAllowedNum > 1) << Values;
5353
76
    }
5354
290
    for (SourceLocation Loc : NameModifierLoc) {
5355
290
      S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5356
290
    }
5357
262
    ErrorFound = true;
5358
262
  }
5359
373k
  return ErrorFound;
5360
373k
}
5361
5362
static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5363
                                                   SourceLocation &ELoc,
5364
                                                   SourceRange &ERange,
5365
                                                   bool AllowArraySection,
5366
463k
                                                   StringRef DiagType) {
5367
463k
  if (RefExpr->isTypeDependent() || 
RefExpr->isValueDependent()425k
||
5368
463k
      
RefExpr->containsUnexpandedParameterPack()425k
)
5369
37.3k
    return std::make_pair(nullptr, true);
5370
5371
  // OpenMP [3.1, C/C++]
5372
  //  A list item is a variable name.
5373
  // OpenMP  [2.9.3.3, Restrictions, p.1]
5374
  //  A variable that is part of another variable (as an array or
5375
  //  structure element) cannot appear in a private clause.
5376
425k
  RefExpr = RefExpr->IgnoreParens();
5377
425k
  enum {
5378
425k
    NoArrayExpr = -1,
5379
425k
    ArraySubscript = 0,
5380
425k
    OMPArraySection = 1
5381
425k
  } IsArrayExpr = NoArrayExpr;
5382
425k
  if (AllowArraySection) {
5383
279k
    if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5384
928
      Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5385
932
      while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5386
4
        Base = TempASE->getBase()->IgnoreParenImpCasts();
5387
928
      RefExpr = Base;
5388
928
      IsArrayExpr = ArraySubscript;
5389
278k
    } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5390
1.50k
      Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5391
2.32k
      while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5392
820
        Base = TempOASE->getBase()->IgnoreParenImpCasts();
5393
1.56k
      while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5394
56
        Base = TempASE->getBase()->IgnoreParenImpCasts();
5395
1.50k
      RefExpr = Base;
5396
1.50k
      IsArrayExpr = OMPArraySection;
5397
1.50k
    }
5398
279k
  }
5399
425k
  ELoc = RefExpr->getExprLoc();
5400
425k
  ERange = RefExpr->getSourceRange();
5401
425k
  RefExpr = RefExpr->IgnoreParenImpCasts();
5402
425k
  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5403
425k
  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5404
425k
  if ((!DE || 
!isa<VarDecl>(DE->getDecl())412k
) &&
5405
425k
      
(12.8k
S.getCurrentThisType().isNull()12.8k
||
!ME5.40k
||
5406
12.8k
       
!isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())5.40k
||
5407
12.8k
       
!isa<FieldDecl>(ME->getMemberDecl())5.17k
)) {
5408
7.62k
    if (IsArrayExpr != NoArrayExpr) {
5409
48
      S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5410
48
          << IsArrayExpr << ERange;
5411
7.57k
    } else if (!DiagType.empty()) {
5412
10
      unsigned DiagSelect = S.getLangOpts().CPlusPlus
5413
10
                                ? 
(8
S.getCurrentThisType().isNull()8
?
16
:
22
)
5414
10
                                : 
02
;
5415
10
      S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5416
10
          << DiagSelect << DiagType << ERange;
5417
7.56k
    } else {
5418
7.56k
      S.Diag(ELoc,
5419
7.56k
             AllowArraySection
5420
7.56k
                 ? 
diag::err_omp_expected_var_name_member_expr_or_array_item5.08k
5421
7.56k
                 : 
diag::err_omp_expected_var_name_member_expr2.47k
)
5422
7.56k
          << (S.getCurrentThisType().isNull() ? 
07.34k
:
1224
) << ERange;
5423
7.56k
    }
5424
7.62k
    return std::make_pair(nullptr, false);
5425
7.62k
  }
5426
418k
  return std::make_pair(
5427
418k
      getCanonicalDecl(DE ? 
DE->getDecl()412k
:
ME->getMemberDecl()5.17k
), false);
5428
425k
}
5429
5430
namespace {
5431
/// Checks if the allocator is used in uses_allocators clause to be allowed in
5432
/// target regions.
5433
class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5434
  DSAStackTy *S = nullptr;
5435
5436
public:
5437
329
  bool VisitDeclRefExpr(const DeclRefExpr *E) {
5438
329
    return S->isUsesAllocatorsDecl(E->getDecl())
5439
329
               .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5440
329
           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5441
329
  }
5442
320
  bool VisitStmt(const Stmt *S) {
5443
320
    for (const Stmt *Child : S->children()) {
5444
320
      if (Child && Visit(Child))
5445
76
        return true;
5446
320
    }
5447
244
    return false;
5448
320
  }
5449
329
  explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5450
};
5451
} // namespace
5452
5453
static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5454
338k
                                 ArrayRef<OMPClause *> Clauses) {
5455
338k
  assert(!S.CurContext->isDependentContext() &&
5456
338k
         "Expected non-dependent context.");
5457
338k
  auto AllocateRange =
5458
338k
      llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5459
338k
  llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5460
338k
  auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5461
253k
    return isOpenMPPrivate(C->getClauseKind());
5462
253k
  });
5463
338k
  for (OMPClause *Cl : PrivateRange) {
5464
120k
    MutableArrayRef<Expr *>::iterator I, It, Et;
5465
120k
    if (Cl->getClauseKind() == OMPC_private) {
5466
13.4k
      auto *PC = cast<OMPPrivateClause>(Cl);
5467
13.4k
      I = PC->private_copies().begin();
5468
13.4k
      It = PC->varlist_begin();
5469
13.4k
      Et = PC->varlist_end();
5470
106k
    } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5471
61.6k
      auto *PC = cast<OMPFirstprivateClause>(Cl);
5472
61.6k
      I = PC->private_copies().begin();
5473
61.6k
      It = PC->varlist_begin();
5474
61.6k
      Et = PC->varlist_end();
5475
61.6k
    } else 
if (45.2k
Cl->getClauseKind() == OMPC_lastprivate45.2k
) {
5476
5.22k
      auto *PC = cast<OMPLastprivateClause>(Cl);
5477
5.22k
      I = PC->private_copies().begin();
5478
5.22k
      It = PC->varlist_begin();
5479
5.22k
      Et = PC->varlist_end();
5480
40.0k
    } else if (Cl->getClauseKind() == OMPC_linear) {
5481
3.13k
      auto *PC = cast<OMPLinearClause>(Cl);
5482
3.13k
      I = PC->privates().begin();
5483
3.13k
      It = PC->varlist_begin();
5484
3.13k
      Et = PC->varlist_end();
5485
36.9k
    } else if (Cl->getClauseKind() == OMPC_reduction) {
5486
28.6k
      auto *PC = cast<OMPReductionClause>(Cl);
5487
28.6k
      I = PC->privates().begin();
5488
28.6k
      It = PC->varlist_begin();
5489
28.6k
      Et = PC->varlist_end();
5490
28.6k
    } else 
if (8.28k
Cl->getClauseKind() == OMPC_task_reduction8.28k
) {
5491
5.09k
      auto *PC = cast<OMPTaskReductionClause>(Cl);
5492
5.09k
      I = PC->privates().begin();
5493
5.09k
      It = PC->varlist_begin();
5494
5.09k
      Et = PC->varlist_end();
5495
5.09k
    } else 
if (3.18k
Cl->getClauseKind() == OMPC_in_reduction3.18k
) {
5496
3.18k
      auto *PC = cast<OMPInReductionClause>(Cl);
5497
3.18k
      I = PC->privates().begin();
5498
3.18k
      It = PC->varlist_begin();
5499
3.18k
      Et = PC->varlist_end();
5500
3.18k
    } else {
5501
0
      llvm_unreachable("Expected private clause.");
5502
0
    }
5503
149k
    for (Expr *E : llvm::make_range(It, Et)) {
5504
149k
      if (!*I) {
5505
939
        ++I;
5506
939
        continue;
5507
939
      }
5508
148k
      SourceLocation ELoc;
5509
148k
      SourceRange ERange;
5510
148k
      Expr *SimpleRefExpr = E;
5511
148k
      auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5512
148k
                                /*AllowArraySection=*/true);
5513
148k
      DeclToCopy.try_emplace(Res.first,
5514
148k
                             cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5515
148k
      ++I;
5516
148k
    }
5517
120k
  }
5518
338k
  for (OMPClause *C : AllocateRange) {
5519
2.17k
    auto *AC = cast<OMPAllocateClause>(C);
5520
2.17k
    if (S.getLangOpts().OpenMP >= 50 &&
5521
2.17k
        
!Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()1.85k
&&
5522
2.17k
        
isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())1.71k
&&
5523
2.17k
        
AC->getAllocator()455
) {
5524
329
      Expr *Allocator = AC->getAllocator();
5525
      // OpenMP, 2.12.5 target Construct
5526
      // Memory allocators that do not appear in a uses_allocators clause cannot
5527
      // appear as an allocator in an allocate clause or be used in the target
5528
      // region unless a requires directive with the dynamic_allocators clause
5529
      // is present in the same compilation unit.
5530
329
      AllocatorChecker Checker(Stack);
5531
329
      if (Checker.Visit(Allocator))
5532
76
        S.Diag(Allocator->getExprLoc(),
5533
76
               diag::err_omp_allocator_not_in_uses_allocators)
5534
76
            << Allocator->getSourceRange();
5535
329
    }
5536
2.17k
    OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5537
2.17k
        getAllocatorKind(S, Stack, AC->getAllocator());
5538
    // OpenMP, 2.11.4 allocate Clause, Restrictions.
5539
    // For task, taskloop or target directives, allocation requests to memory
5540
    // allocators with the trait access set to thread result in unspecified
5541
    // behavior.
5542
2.17k
    if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5543
2.17k
        
(1.25k
isOpenMPTaskingDirective(Stack->getCurrentDirective())1.25k
||
5544
1.25k
         
isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())483
)) {
5545
1.24k
      S.Diag(AC->getAllocator()->getExprLoc(),
5546
1.24k
             diag::warn_omp_allocate_thread_on_task_target_directive)
5547
1.24k
          << getOpenMPDirectiveName(Stack->getCurrentDirective());
5548
1.24k
    }
5549
2.17k
    for (Expr *E : AC->varlists()) {
5550
2.17k
      SourceLocation ELoc;
5551
2.17k
      SourceRange ERange;
5552
2.17k
      Expr *SimpleRefExpr = E;
5553
2.17k
      auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5554
2.17k
      ValueDecl *VD = Res.first;
5555
2.17k
      DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5556
2.17k
      if (!isOpenMPPrivate(Data.CKind)) {
5557
4
        S.Diag(E->getExprLoc(),
5558
4
               diag::err_omp_expected_private_copy_for_allocate);
5559
4
        continue;
5560
4
      }
5561
2.16k
      VarDecl *PrivateVD = DeclToCopy[VD];
5562
2.16k
      if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5563
2.16k
                                            AllocatorKind, AC->getAllocator()))
5564
0
        continue;
5565
      // Placeholder until allocate clause supports align modifier.
5566
2.16k
      Expr *Alignment = nullptr;
5567
2.16k
      applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5568
2.16k
                                Alignment, E->getSourceRange());
5569
2.16k
    }
5570
2.17k
  }
5571
338k
}
5572
5573
namespace {
5574
/// Rewrite statements and expressions for Sema \p Actions CurContext.
5575
///
5576
/// Used to wrap already parsed statements/expressions into a new CapturedStmt
5577
/// context. DeclRefExpr used inside the new context are changed to refer to the
5578
/// captured variable instead.
5579
class CaptureVars : public TreeTransform<CaptureVars> {
5580
  using BaseTransform = TreeTransform<CaptureVars>;
5581
5582
public:
5583
480
  CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5584
5585
696
  bool AlwaysRebuild() { return true; }
5586
};
5587
} // namespace
5588
5589
static VarDecl *precomputeExpr(Sema &Actions,
5590
                               SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5591
318
                               StringRef Name) {
5592
318
  Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5593
318
  VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5594
318
                                 dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5595
318
  auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5596
318
      Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5597
318
  Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5598
318
  BodyStmts.push_back(NewDeclStmt);
5599
318
  return NewVar;
5600
318
}
5601
5602
/// Create a closure that computes the number of iterations of a loop.
5603
///
5604
/// \param Actions   The Sema object.
5605
/// \param LogicalTy Type for the logical iteration number.
5606
/// \param Rel       Comparison operator of the loop condition.
5607
/// \param StartExpr Value of the loop counter at the first iteration.
5608
/// \param StopExpr  Expression the loop counter is compared against in the loop
5609
/// condition. \param StepExpr      Amount of increment after each iteration.
5610
///
5611
/// \return Closure (CapturedStmt) of the distance calculation.
5612
static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5613
                                       BinaryOperator::Opcode Rel,
5614
                                       Expr *StartExpr, Expr *StopExpr,
5615
106
                                       Expr *StepExpr) {
5616
106
  ASTContext &Ctx = Actions.getASTContext();
5617
106
  TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5618
5619
  // Captured regions currently don't support return values, we use an
5620
  // out-parameter instead. All inputs are implicit captures.
5621
  // TODO: Instead of capturing each DeclRefExpr occurring in
5622
  // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5623
106
  QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5624
106
  Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5625
106
                                          {StringRef(), QualType()}};
5626
106
  Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5627
5628
106
  Stmt *Body;
5629
106
  {
5630
106
    Sema::CompoundScopeRAII CompoundScope(Actions);
5631
106
    CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5632
5633
    // Get the LValue expression for the result.
5634
106
    ImplicitParamDecl *DistParam = CS->getParam(0);
5635
106
    DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5636
106
        DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5637
5638
106
    SmallVector<Stmt *, 4> BodyStmts;
5639
5640
    // Capture all referenced variable references.
5641
    // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5642
    // CapturedStmt, we could compute them before and capture the result, to be
5643
    // used jointly with the LoopVar function.
5644
106
    VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5645
106
    VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5646
106
    VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5647
534
    auto BuildVarRef = [&](VarDecl *VD) {
5648
534
      return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5649
534
    };
5650
5651
106
    IntegerLiteral *Zero = IntegerLiteral::Create(
5652
106
        Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5653
106
    IntegerLiteral *One = IntegerLiteral::Create(
5654
106
        Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5655
106
    Expr *Dist;
5656
106
    if (Rel == BO_NE) {
5657
      // When using a != comparison, the increment can be +1 or -1. This can be
5658
      // dynamic at runtime, so we need to check for the direction.
5659
2
      Expr *IsNegStep = AssertSuccess(
5660
2
          Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5661
5662
      // Positive increment.
5663
2
      Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5664
2
          nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5665
2
      ForwardRange = AssertSuccess(
5666
2
          Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5667
2
      Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5668
2
          nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5669
5670
      // Negative increment.
5671
2
      Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5672
2
          nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5673
2
      BackwardRange = AssertSuccess(
5674
2
          Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5675
2
      Expr *NegIncAmount = AssertSuccess(
5676
2
          Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5677
2
      Expr *BackwardDist = AssertSuccess(
5678
2
          Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5679
5680
      // Use the appropriate case.
5681
2
      Dist = AssertSuccess(Actions.ActOnConditionalOp(
5682
2
          {}, {}, IsNegStep, BackwardDist, ForwardDist));
5683
104
    } else {
5684
104
      assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5685
104
             "Expected one of these relational operators");
5686
5687
      // We can derive the direction from any other comparison operator. It is
5688
      // non well-formed OpenMP if Step increments/decrements in the other
5689
      // directions. Whether at least the first iteration passes the loop
5690
      // condition.
5691
104
      Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5692
104
          nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5693
5694
      // Compute the range between first and last counter value.
5695
104
      Expr *Range;
5696
104
      if (Rel == BO_GE || Rel == BO_GT)
5697
7
        Range = AssertSuccess(Actions.BuildBinOp(
5698
7
            nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5699
97
      else
5700
97
        Range = AssertSuccess(Actions.BuildBinOp(
5701
97
            nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5702
5703
      // Ensure unsigned range space.
5704
104
      Range =
5705
104
          AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5706
5707
104
      if (Rel == BO_LE || 
Rel == BO_GE96
) {
5708
        // Add one to the range if the relational operator is inclusive.
5709
8
        Range =
5710
8
            AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5711
8
      }
5712
5713
      // Divide by the absolute step amount. If the range is not a multiple of
5714
      // the step size, rounding-up the effective upper bound ensures that the
5715
      // last iteration is included.
5716
      // Note that the rounding-up may cause an overflow in a temporry that
5717
      // could be avoided, but would have occurred in a C-style for-loop as
5718
      // well.
5719
104
      Expr *Divisor = BuildVarRef(NewStep);
5720
104
      if (Rel == BO_GE || Rel == BO_GT)
5721
7
        Divisor =
5722
7
            AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5723
104
      Expr *DivisorMinusOne =
5724
104
          AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5725
104
      Expr *RangeRoundUp = AssertSuccess(
5726
104
          Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5727
104
      Dist = AssertSuccess(
5728
104
          Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5729
5730
      // If there is not at least one iteration, the range contains garbage. Fix
5731
      // to zero in this case.
5732
104
      Dist = AssertSuccess(
5733
104
          Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5734
104
    }
5735
5736
    // Assign the result to the out-parameter.
5737
106
    Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5738
106
        Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5739
106
    BodyStmts.push_back(ResultAssign);
5740
5741
106
    Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5742
106
  }
5743
5744
0
  return cast<CapturedStmt>(
5745
106
      AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5746
106
}
5747
5748
/// Create a closure that computes the loop variable from the logical iteration
5749
/// number.
5750
///
5751
/// \param Actions   The Sema object.
5752
/// \param LoopVarTy Type for the loop variable used for result value.
5753
/// \param LogicalTy Type for the logical iteration number.
5754
/// \param StartExpr Value of the loop counter at the first iteration.
5755
/// \param Step      Amount of increment after each iteration.
5756
/// \param Deref     Whether the loop variable is a dereference of the loop
5757
/// counter variable.
5758
///
5759
/// \return Closure (CapturedStmt) of the loop value calculation.
5760
static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5761
                                      QualType LogicalTy,
5762
                                      DeclRefExpr *StartExpr, Expr *Step,
5763
106
                                      bool Deref) {
5764
106
  ASTContext &Ctx = Actions.getASTContext();
5765
5766
  // Pass the result as an out-parameter. Passing as return value would require
5767
  // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5768
  // invoke a copy constructor.
5769
106
  QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5770
106
  Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5771
106
                                          {"Logical", LogicalTy},
5772
106
                                          {StringRef(), QualType()}};
5773
106
  Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5774
5775
  // Capture the initial iterator which represents the LoopVar value at the
5776
  // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5777
  // it in every iteration, capture it by value before it is modified.
5778
106
  VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5779
106
  bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5780
106
                                            Sema::TryCapture_ExplicitByVal, {});
5781
106
  (void)Invalid;
5782
106
  assert(!Invalid && "Expecting capture-by-value to work.");
5783
5784
106
  Expr *Body;
5785
106
  {
5786
106
    Sema::CompoundScopeRAII CompoundScope(Actions);
5787
106
    auto *CS = cast<CapturedDecl>(Actions.CurContext);
5788
5789
106
    ImplicitParamDecl *TargetParam = CS->getParam(0);
5790
106
    DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5791
106
        TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5792
106
    ImplicitParamDecl *IndvarParam = CS->getParam(1);
5793
106
    DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5794
106
        IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5795
5796
    // Capture the Start expression.
5797
106
    CaptureVars Recap(Actions);
5798
106
    Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5799
106
    Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5800
5801
106
    Expr *Skip = AssertSuccess(
5802
106
        Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5803
    // TODO: Explicitly cast to the iterator's difference_type instead of
5804
    // relying on implicit conversion.
5805
106
    Expr *Advanced =
5806
106
        AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5807
5808
106
    if (Deref) {
5809
      // For range-based for-loops convert the loop counter value to a concrete
5810
      // loop variable value by dereferencing the iterator.
5811
1
      Advanced =
5812
1
          AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5813
1
    }
5814
5815
    // Assign the result to the output parameter.
5816
106
    Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5817
106
                                            BO_Assign, TargetRef, Advanced));
5818
106
  }
5819
106
  return cast<CapturedStmt>(
5820
106
      AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5821
106
}
5822
5823
106
StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5824
106
  ASTContext &Ctx = getASTContext();
5825
5826
  // Extract the common elements of ForStmt and CXXForRangeStmt:
5827
  // Loop variable, repeat condition, increment
5828
106
  Expr *Cond, *Inc;
5829
106
  VarDecl *LIVDecl, *LUVDecl;
5830
106
  if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5831
105
    Stmt *Init = For->getInit();
5832
105
    if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5833
      // For statement declares loop variable.
5834
97
      LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5835
97
    } else 
if (auto *8
LCAssign8
= dyn_cast<BinaryOperator>(Init)) {
5836
      // For statement reuses variable.
5837
8
      assert(LCAssign->getOpcode() == BO_Assign &&
5838
8
             "init part must be a loop variable assignment");
5839
8
      auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5840
8
      LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5841
8
    } else
5842
0
      llvm_unreachable("Cannot determine loop variable");
5843
105
    LUVDecl = LIVDecl;
5844
5845
105
    Cond = For->getCond();
5846
105
    Inc = For->getInc();
5847
105
  } else 
if (auto *1
RangeFor1
= dyn_cast<CXXForRangeStmt>(AStmt)) {
5848
1
    DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5849
1
    LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5850
1
    LUVDecl = RangeFor->getLoopVariable();
5851
5852
1
    Cond = RangeFor->getCond();
5853
1
    Inc = RangeFor->getInc();
5854
1
  } else
5855
0
    llvm_unreachable("unhandled kind of loop");
5856
5857
106
  QualType CounterTy = LIVDecl->getType();
5858
106
  QualType LVTy = LUVDecl->getType();
5859
5860
  // Analyze the loop condition.
5861
106
  Expr *LHS, *RHS;
5862
106
  BinaryOperator::Opcode CondRel;
5863
106
  Cond = Cond->IgnoreImplicit();
5864
106
  if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5865
104
    LHS = CondBinExpr->getLHS();
5866
104
    RHS = CondBinExpr->getRHS();
5867
104
    CondRel = CondBinExpr->getOpcode();
5868
104
  } else 
if (auto *2
CondCXXOp2
= dyn_cast<CXXOperatorCallExpr>(Cond)) {
5869
2
    assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5870
2
    LHS = CondCXXOp->getArg(0);
5871
2
    RHS = CondCXXOp->getArg(1);
5872
2
    switch (CondCXXOp->getOperator()) {
5873
2
    case OO_ExclaimEqual:
5874
2
      CondRel = BO_NE;
5875
2
      break;
5876
0
    case OO_Less:
5877
0
      CondRel = BO_LT;
5878
0
      break;
5879
0
    case OO_LessEqual:
5880
0
      CondRel = BO_LE;
5881
0
      break;
5882
0
    case OO_Greater:
5883
0
      CondRel = BO_GT;
5884
0
      break;
5885
0
    case OO_GreaterEqual:
5886
0
      CondRel = BO_GE;
5887
0
      break;
5888
0
    default:
5889
0
      llvm_unreachable("unexpected iterator operator");
5890
2
    }
5891
2
  } else
5892
0
    llvm_unreachable("unexpected loop condition");
5893
5894
  // Normalize such that the loop counter is on the LHS.
5895
106
  if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5896
106
      cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5897
0
    std::swap(LHS, RHS);
5898
0
    CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5899
0
  }
5900
106
  auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5901
5902
  // Decide the bit width for the logical iteration counter. By default use the
5903
  // unsigned ptrdiff_t integer size (for iterators and pointers).
5904
  // TODO: For iterators, use iterator::difference_type,
5905
  // std::iterator_traits<>::difference_type or decltype(it - end).
5906
106
  QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5907
106
  if (CounterTy->isIntegerType()) {
5908
102
    unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5909
102
    LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5910
102
  }
5911
5912
  // Analyze the loop increment.
5913
106
  Expr *Step;
5914
106
  if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5915
77
    int Direction;
5916
77
    switch (IncUn->getOpcode()) {
5917
52
    case UO_PreInc:
5918
75
    case UO_PostInc:
5919
75
      Direction = 1;
5920
75
      break;
5921
2
    case UO_PreDec:
5922
2
    case UO_PostDec:
5923
2
      Direction = -1;
5924
2
      break;
5925
0
    default:
5926
0
      llvm_unreachable("unhandled unary increment operator");
5927
77
    }
5928
77
    Step = IntegerLiteral::Create(
5929
77
        Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5930
77
  } else 
if (auto *29
IncBin29
= dyn_cast<BinaryOperator>(Inc)) {
5931
27
    if (IncBin->getOpcode() == BO_AddAssign) {
5932
26
      Step = IncBin->getRHS();
5933
26
    } else 
if (1
IncBin->getOpcode() == BO_SubAssign1
) {
5934
1
      Step =
5935
1
          AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5936
1
    } else
5937
0
      llvm_unreachable("unhandled binary increment operator");
5938
27
  } else 
if (auto *2
CondCXXOp2
= dyn_cast<CXXOperatorCallExpr>(Inc)) {
5939
2
    switch (CondCXXOp->getOperator()) {
5940
2
    case OO_PlusPlus:
5941
2
      Step = IntegerLiteral::Create(
5942
2
          Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5943
2
      break;
5944
0
    case OO_MinusMinus:
5945
0
      Step = IntegerLiteral::Create(
5946
0
          Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5947
0
      break;
5948
0
    case OO_PlusEqual:
5949
0
      Step = CondCXXOp->getArg(1);
5950
0
      break;
5951
0
    case OO_MinusEqual:
5952
0
      Step = AssertSuccess(
5953
0
          BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5954
0
      break;
5955
0
    default:
5956
0
      llvm_unreachable("unhandled overloaded increment operator");
5957
2
    }
5958
2
  } else
5959
0
    llvm_unreachable("unknown increment expression");
5960
5961
106
  CapturedStmt *DistanceFunc =
5962
106
      buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5963
106
  CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5964
106
      *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5965
106
  DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5966
106
                                        {}, nullptr, nullptr, {}, nullptr);
5967
106
  return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5968
106
                                  LoopVarFunc, LVRef);
5969
106
}
5970
5971
109
StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5972
  // Handle a literal loop.
5973
109
  if (isa<ForStmt>(AStmt) || 
isa<CXXForRangeStmt>(AStmt)6
)
5974
104
    return ActOnOpenMPCanonicalLoop(AStmt);
5975
5976
  // If not a literal loop, it must be the result of a loop transformation.
5977
5
  OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5978
5
  assert(
5979
5
      isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&
5980
5
      "Loop transformation directive expected");
5981
5
  return LoopTransform;
5982
5
}
5983
5984
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5985
                                            CXXScopeSpec &MapperIdScopeSpec,
5986
                                            const DeclarationNameInfo &MapperId,
5987
                                            QualType Type,
5988
                                            Expr *UnresolvedMapper);
5989
5990
/// Perform DFS through the structure/class data members trying to find
5991
/// member(s) with user-defined 'default' mapper and generate implicit map
5992
/// clauses for such members with the found 'default' mapper.
5993
static void
5994
processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5995
240k
                                      SmallVectorImpl<OMPClause *> &Clauses) {
5996
  // Check for the deault mapper for data members.
5997
240k
  if (S.getLangOpts().OpenMP < 50)
5998
0
    return;
5999
240k
  SmallVector<OMPClause *, 4> ImplicitMaps;
6000
413k
  for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; 
++Cnt172k
) {
6001
172k
    auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
6002
172k
    if (!C)
6003
142k
      continue;
6004
30.1k
    SmallVector<Expr *, 4> SubExprs;
6005
30.1k
    auto *MI = C->mapperlist_begin();
6006
66.2k
    for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
6007
36.1k
         ++I, ++MI) {
6008
      // Expression is mapped using mapper - skip it.
6009
36.1k
      if (*MI)
6010
308
        continue;
6011
35.8k
      Expr *E = *I;
6012
      // Expression is dependent - skip it, build the mapper when it gets
6013
      // instantiated.
6014
35.8k
      if (E->isTypeDependent() || E->isValueDependent() ||
6015
35.8k
          E->containsUnexpandedParameterPack())
6016
0
        continue;
6017
      // Array section - need to check for the mapping of the array section
6018
      // element.
6019
35.8k
      QualType CanonType = E->getType().getCanonicalType();
6020
35.8k
      if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
6021
4.43k
        const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
6022
4.43k
        QualType BaseType =
6023
4.43k
            OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
6024
4.43k
        QualType ElemType;
6025
4.43k
        if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
6026
2.76k
          ElemType = ATy->getElementType();
6027
1.67k
        else
6028
1.67k
          ElemType = BaseType->getPointeeType();
6029
4.43k
        CanonType = ElemType;
6030
4.43k
      }
6031
6032
      // DFS over data members in structures/classes.
6033
35.8k
      SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
6034
35.8k
          1, {CanonType, nullptr});
6035
35.8k
      llvm::DenseMap<const Type *, Expr *> Visited;
6036
35.8k
      SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
6037
35.8k
          1, {nullptr, 1});
6038
71.8k
      while (!Types.empty()) {
6039
35.9k
        QualType BaseType;
6040
35.9k
        FieldDecl *CurFD;
6041
35.9k
        std::tie(BaseType, CurFD) = Types.pop_back_val();
6042
35.9k
        while (ParentChain.back().second == 0)
6043
0
          ParentChain.pop_back();
6044
35.9k
        --ParentChain.back().second;
6045
35.9k
        if (BaseType.isNull())
6046
0
          continue;
6047
        // Only structs/classes are allowed to have mappers.
6048
35.9k
        const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
6049
35.9k
        if (!RD)
6050
29.5k
          continue;
6051
6.44k
        auto It = Visited.find(BaseType.getTypePtr());
6052
6.44k
        if (It == Visited.end()) {
6053
          // Try to find the associated user-defined mapper.
6054
6.44k
          CXXScopeSpec MapperIdScopeSpec;
6055
6.44k
          DeclarationNameInfo DefaultMapperId;
6056
6.44k
          DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
6057
6.44k
              &S.Context.Idents.get("default")));
6058
6.44k
          DefaultMapperId.setLoc(E->getExprLoc());
6059
6.44k
          ExprResult ER = buildUserDefinedMapperRef(
6060
6.44k
              S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6061
6.44k
              BaseType, /*UnresolvedMapper=*/nullptr);
6062
6.44k
          if (ER.isInvalid())
6063
0
            continue;
6064
6.44k
          It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
6065
6.44k
        }
6066
        // Found default mapper.
6067
6.44k
        if (It->second) {
6068
16
          auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
6069
16
                                                     VK_LValue, OK_Ordinary, E);
6070
16
          OE->setIsUnique(/*V=*/true);
6071
16
          Expr *BaseExpr = OE;
6072
32
          for (const auto &P : ParentChain) {
6073
32
            if (P.first) {
6074
0
              BaseExpr = S.BuildMemberExpr(
6075
0
                  BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6076
0
                  NestedNameSpecifierLoc(), SourceLocation(), P.first,
6077
0
                  DeclAccessPair::make(P.first, P.first->getAccess()),
6078
0
                  /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6079
0
                  P.first->getType(), VK_LValue, OK_Ordinary);
6080
0
              BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
6081
0
            }
6082
32
          }
6083
16
          if (CurFD)
6084
16
            BaseExpr = S.BuildMemberExpr(
6085
16
                BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6086
16
                NestedNameSpecifierLoc(), SourceLocation(), CurFD,
6087
16
                DeclAccessPair::make(CurFD, CurFD->getAccess()),
6088
16
                /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6089
16
                CurFD->getType(), VK_LValue, OK_Ordinary);
6090
16
          SubExprs.push_back(BaseExpr);
6091
16
          continue;
6092
16
        }
6093
        // Check for the "default" mapper for data members.
6094
6.43k
        bool FirstIter = true;
6095
7.95k
        for (FieldDecl *FD : RD->fields()) {
6096
7.95k
          if (!FD)
6097
0
            continue;
6098
7.95k
          QualType FieldTy = FD->getType();
6099
7.95k
          if (FieldTy.isNull() ||
6100
7.95k
              !(FieldTy->isStructureOrClassType() || 
FieldTy->isUnionType()7.81k
))
6101
7.81k
            continue;
6102
138
          if (FirstIter) {
6103
138
            FirstIter = false;
6104
138
            ParentChain.emplace_back(CurFD, 1);
6105
138
          } else {
6106
0
            ++ParentChain.back().second;
6107
0
          }
6108
138
          Types.emplace_back(FieldTy, FD);
6109
138
        }
6110
6.43k
      }
6111
35.8k
    }
6112
30.1k
    if (SubExprs.empty())
6113
30.0k
      continue;
6114
16
    CXXScopeSpec MapperIdScopeSpec;
6115
16
    DeclarationNameInfo MapperId;
6116
16
    if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
6117
16
            nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
6118
16
            MapperIdScopeSpec, MapperId, C->getMapType(),
6119
16
            /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6120
16
            SubExprs, OMPVarListLocTy()))
6121
16
      Clauses.push_back(NewClause);
6122
16
  }
6123
240k
}
6124
6125
bool Sema::mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
6126
                            ArrayRef<OMPClause *> Clauses,
6127
                            OpenMPBindClauseKind BindKind,
6128
                            OpenMPDirectiveKind &Kind,
6129
484k
                            OpenMPDirectiveKind &PrevMappedDirective) {
6130
6131
484k
  bool UseClausesWithoutBind = false;
6132
6133
  // Restricting to "#pragma omp loop bind"
6134
484k
  if (getLangOpts().OpenMP >= 50 && 
Kind == OMPD_loop360k
) {
6135
90
    if (BindKind == OMPC_BIND_unknown) {
6136
      // Setting the enclosing teams or parallel construct for the loop
6137
      // directive without bind clause.
6138
35
      BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown
6139
6140
35
      const OpenMPDirectiveKind ParentDirective =
6141
35
          DSAStack->getParentDirective();
6142
35
      if (ParentDirective == OMPD_unknown) {
6143
1
        Diag(DSAStack->getDefaultDSALocation(),
6144
1
             diag::err_omp_bind_required_on_loop);
6145
34
      } else if (ParentDirective == OMPD_parallel ||
6146
34
                 
ParentDirective == OMPD_target_parallel14
) {
6147
20
        BindKind = OMPC_BIND_parallel;
6148
20
      } else 
if (14
ParentDirective == OMPD_teams14
||
6149
14
                 ParentDirective == OMPD_target_teams) {
6150
4
        BindKind = OMPC_BIND_teams;
6151
4
      }
6152
55
    } else {
6153
      // bind clause is present, so we should set flag indicating to only
6154
      // use the clauses that aren't the bind clause for the new directive that
6155
      // loop is lowered to.
6156
55
      UseClausesWithoutBind = true;
6157
55
    }
6158
6159
106
    for (OMPClause *C : Clauses) {
6160
      // Spec restriction : bind(teams) and reduction not permitted.
6161
106
      if (BindKind == OMPC_BIND_teams &&
6162
106
          
C->getClauseKind() == llvm::omp::Clause::OMPC_reduction18
)
6163
1
        Diag(DSAStack->getDefaultDSALocation(),
6164
1
             diag::err_omp_loop_reduction_clause);
6165
6166
      // A new Vector ClausesWithoutBind, which does not contain the bind
6167
      // clause, for passing to new directive.
6168
106
      if (C->getClauseKind() != llvm::omp::Clause::OMPC_bind)
6169
51
        ClausesWithoutBind.push_back(C);
6170
106
    }
6171
6172
90
    switch (BindKind) {
6173
32
    case OMPC_BIND_parallel:
6174
32
      Kind = OMPD_for;
6175
32
      DSAStack->setCurrentDirective(OMPD_for);
6176
32
      DSAStack->setMappedDirective(OMPD_loop);
6177
32
      PrevMappedDirective = OMPD_loop;
6178
32
      break;
6179
19
    case OMPC_BIND_teams:
6180
19
      Kind = OMPD_distribute;
6181
19
      DSAStack->setCurrentDirective(OMPD_distribute);
6182
19
      DSAStack->setMappedDirective(OMPD_loop);
6183
19
      PrevMappedDirective = OMPD_loop;
6184
19
      break;
6185
39
    case OMPC_BIND_thread:
6186
39
      Kind = OMPD_simd;
6187
39
      DSAStack->setCurrentDirective(OMPD_simd);
6188
39
      DSAStack->setMappedDirective(OMPD_loop);
6189
39
      PrevMappedDirective = OMPD_loop;
6190
39
      break;
6191
0
    case OMPC_BIND_unknown:
6192
0
      break;
6193
90
    }
6194
484k
  } else if (PrevMappedDirective == OMPD_loop) {
6195
    /// An initial pass after recognizing all the statements is done in the
6196
    /// Parser when the directive OMPD_loop is mapped to OMPD_for,
6197
    /// OMPD_distribute or OMPD_simd. A second transform pass with call from
6198
    /// clang::TreeTransform::TransformOMPExecutableDirective() is done
6199
    /// with the Directive as one of the above mapped directive without
6200
    /// the bind clause. Then "PrevMappedDirective" stored in the
6201
    /// OMPExecutableDirective is accessed and hence this else statement.
6202
6203
7
    DSAStack->setMappedDirective(OMPD_loop);
6204
7
  }
6205
6206
484k
  return UseClausesWithoutBind;
6207
484k
}
6208
6209
StmtResult Sema::ActOnOpenMPExecutableDirective(
6210
    OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
6211
    OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
6212
    Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
6213
502k
    OpenMPDirectiveKind PrevMappedDirective) {
6214
502k
  StmtResult Res = StmtError();
6215
502k
  OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
6216
502k
  if (const OMPBindClause *BC =
6217
502k
          OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6218
194
    BindKind = BC->getBindKind();
6219
  // First check CancelRegion which is then used in checkNestingOfRegions.
6220
502k
  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6221
502k
      
checkNestingOfRegions(*this, 502k
DSAStack502k
, Kind, DirName, CancelRegion,
6222
502k
                            BindKind, StartLoc))
6223
17.7k
    return StmtError();
6224
6225
  // Report affected OpenMP target offloading behavior when in HIP lang-mode.
6226
484k
  if (getLangOpts().HIP && 
(25
isOpenMPTargetExecutionDirective(Kind)25
||
6227
25
                            
isOpenMPTargetDataManagementDirective(Kind)9
))
6228
20
    Diag(StartLoc, diag::warn_hip_omp_target_directives);
6229
6230
484k
  llvm::SmallVector<OMPClause *> ClausesWithoutBind;
6231
484k
  bool UseClausesWithoutBind = false;
6232
6233
484k
  UseClausesWithoutBind = mapLoopConstruct(ClausesWithoutBind, Clauses,
6234
484k
                                           BindKind, Kind, PrevMappedDirective);
6235
6236
484k
  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
6237
484k
  VarsWithInheritedDSAType VarsWithInheritedDSA;
6238
484k
  bool ErrorFound = false;
6239
484k
  if (getLangOpts().OpenMP >= 50 && 
UseClausesWithoutBind360k
) {
6240
55
    ClausesWithImplicit.append(ClausesWithoutBind.begin(),
6241
55
                               ClausesWithoutBind.end());
6242
484k
  } else {
6243
484k
    ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6244
484k
  }
6245
484k
  if (AStmt && 
!CurContext->isDependentContext()471k
&&
Kind != OMPD_atomic347k
&&
6246
484k
      
Kind != OMPD_critical329k
&&
Kind != OMPD_section327k
&&
Kind != OMPD_master327k
&&
6247
484k
      
Kind != OMPD_masked325k
&&
!isOpenMPLoopTransformationDirective(Kind)325k
) {
6248
325k
    assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6249
6250
    // Check default data sharing attributes for referenced variables.
6251
325k
    DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
6252
325k
    int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6253
325k
    Stmt *S = AStmt;
6254
878k
    while (--ThisCaptureLevel >= 0)
6255
553k
      S = cast<CapturedStmt>(S)->getCapturedStmt();
6256
325k
    DSAChecker.Visit(S);
6257
325k
    if (!isOpenMPTargetDataManagementDirective(Kind) &&
6258
325k
        
!isOpenMPTaskingDirective(Kind)314k
) {
6259
      // Visit subcaptures to generate implicit clauses for captured vars.
6260
266k
      auto *CS = cast<CapturedStmt>(AStmt);
6261
266k
      SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
6262
266k
      getOpenMPCaptureRegions(CaptureRegions, Kind);
6263
      // Ignore outer tasking regions for target directives.
6264
266k
      if (CaptureRegions.size() > 1 && 
CaptureRegions.front() == OMPD_task134k
)
6265
124k
        CS = cast<CapturedStmt>(CS->getCapturedStmt());
6266
266k
      DSAChecker.visitSubCaptures(CS);
6267
266k
    }
6268
325k
    if (DSAChecker.isErrorFound())
6269
84
      return StmtError();
6270
    // Generate list of implicitly defined firstprivate variables.
6271
325k
    VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6272
6273
325k
    SmallVector<Expr *, 4> ImplicitFirstprivates(
6274
325k
        DSAChecker.getImplicitFirstprivate().begin(),
6275
325k
        DSAChecker.getImplicitFirstprivate().end());
6276
325k
    SmallVector<Expr *, 4> ImplicitPrivates(
6277
325k
        DSAChecker.getImplicitPrivate().begin(),
6278
325k
        DSAChecker.getImplicitPrivate().end());
6279
325k
    const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
6280
325k
    SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
6281
325k
    SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
6282
325k
        ImplicitMapModifiers[DefaultmapKindNum];
6283
325k
    SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
6284
325k
        ImplicitMapModifiersLoc[DefaultmapKindNum];
6285
    // Get the original location of present modifier from Defaultmap clause.
6286
325k
    SourceLocation PresentModifierLocs[DefaultmapKindNum];
6287
325k
    for (OMPClause *C : Clauses) {
6288
151k
      if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
6289
2.02k
        if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6290
70
          PresentModifierLocs[DMC->getDefaultmapKind()] =
6291
70
              DMC->getDefaultmapModifierLoc();
6292
151k
    }
6293
1.30M
    for (unsigned VC = 0; VC < DefaultmapKindNum; 
++VC976k
) {
6294
976k
      auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
6295
4.88M
      for (unsigned I = 0; I < OMPC_MAP_delete; 
++I3.90M
) {
6296
3.90M
        ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
6297
3.90M
            Kind, static_cast<OpenMPMapClauseKind>(I));
6298
3.90M
        ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6299
3.90M
      }
6300
976k
      ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
6301
976k
          DSAChecker.getImplicitMapModifier(Kind);
6302
976k
      ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6303
976k
                                      ImplicitModifier.end());
6304
976k
      std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6305
976k
                  ImplicitModifier.size(), PresentModifierLocs[VC]);
6306
976k
    }
6307
    // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6308
325k
    for (OMPClause *C : Clauses) {
6309
151k
      if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
6310
3.18k
        for (Expr *E : IRC->taskgroup_descriptors())
6311
3.64k
          if (E)
6312
2.91k
            ImplicitFirstprivates.emplace_back(E);
6313
3.18k
      }
6314
      // OpenMP 5.0, 2.10.1 task Construct
6315
      // [detach clause]... The event-handle will be considered as if it was
6316
      // specified on a firstprivate clause.
6317
151k
      if (auto *DC = dyn_cast<OMPDetachClause>(C))
6318
53
        ImplicitFirstprivates.push_back(DC->getEventHandler());
6319
151k
    }
6320
325k
    if (!ImplicitFirstprivates.empty()) {
6321
57.5k
      if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6322
57.5k
              ImplicitFirstprivates, SourceLocation(), SourceLocation(),
6323
57.5k
              SourceLocation())) {
6324
57.5k
        ClausesWithImplicit.push_back(Implicit);
6325
57.5k
        ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6326
57.5k
                     ImplicitFirstprivates.size();
6327
57.5k
      } else {
6328
0
        ErrorFound = true;
6329
0
      }
6330
57.5k
    }
6331
325k
    if (!ImplicitPrivates.empty()) {
6332
28
      if (OMPClause *Implicit =
6333
28
              ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(),
6334
28
                                       SourceLocation(), SourceLocation())) {
6335
28
        ClausesWithImplicit.push_back(Implicit);
6336
28
        ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6337
28
                     ImplicitPrivates.size();
6338
28
      } else {
6339
0
        ErrorFound = true;
6340
0
      }
6341
28
    }
6342
    // OpenMP 5.0 [2.19.7]
6343
    // If a list item appears in a reduction, lastprivate or linear
6344
    // clause on a combined target construct then it is treated as
6345
    // if it also appears in a map clause with a map-type of tofrom
6346
325k
    if (getLangOpts().OpenMP >= 50 && 
Kind != OMPD_target240k
&&
6347
325k
        
isOpenMPTargetExecutionDirective(Kind)201k
) {
6348
49.7k
      SmallVector<Expr *, 4> ImplicitExprs;
6349
49.7k
      for (OMPClause *C : Clauses) {
6350
31.8k
        if (auto *RC = dyn_cast<OMPReductionClause>(C))
6351
4.87k
          for (Expr *E : RC->varlists())
6352
6.10k
            if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
6353
260
              ImplicitExprs.emplace_back(E);
6354
31.8k
      }
6355
49.7k
      if (!ImplicitExprs.empty()) {
6356
180
        ArrayRef<Expr *> Exprs = ImplicitExprs;
6357
180
        CXXScopeSpec MapperIdScopeSpec;
6358
180
        DeclarationNameInfo MapperId;
6359
180
        if (OMPClause *Implicit = ActOnOpenMPMapClause(
6360
180
                nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(),
6361
180
                MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6362
180
                /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6363
180
                Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
6364
180
          ClausesWithImplicit.emplace_back(Implicit);
6365
180
      }
6366
49.7k
    }
6367
1.30M
    for (unsigned I = 0, E = DefaultmapKindNum; I < E; 
++I976k
) {
6368
976k
      int ClauseKindCnt = -1;
6369
3.90M
      for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
6370
3.90M
        ++ClauseKindCnt;
6371
3.90M
        if (ImplicitMap.empty())
6372
3.89M
          continue;
6373
12.9k
        CXXScopeSpec MapperIdScopeSpec;
6374
12.9k
        DeclarationNameInfo MapperId;
6375
12.9k
        auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
6376
12.9k
        if (OMPClause *Implicit = ActOnOpenMPMapClause(
6377
12.9k
                nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6378
12.9k
                MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
6379
12.9k
                SourceLocation(), SourceLocation(), ImplicitMap,
6380
12.9k
                OMPVarListLocTy())) {
6381
12.9k
          ClausesWithImplicit.emplace_back(Implicit);
6382
12.9k
          ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6383
12.9k
                        ImplicitMap.size();
6384
12.9k
        } else {
6385
0
          ErrorFound = true;
6386
0
        }
6387
12.9k
      }
6388
976k
    }
6389
    // Build expressions for implicit maps of data members with 'default'
6390
    // mappers.
6391
325k
    if (LangOpts.OpenMP >= 50)
6392
240k
      processImplicitMapsWithDefaultMappers(*this, DSAStack,
6393
240k
                                            ClausesWithImplicit);
6394
325k
  }
6395
6396
484k
  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
6397
484k
  switch (Kind) {
6398
43.7k
  case OMPD_parallel:
6399
43.7k
    Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6400
43.7k
                                       EndLoc);
6401
43.7k
    AllowedNameModifiers.push_back(OMPD_parallel);
6402
43.7k
    break;
6403
8.98k
  case OMPD_simd:
6404
8.98k
    Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6405
8.98k
                                   VarsWithInheritedDSA);
6406
8.98k
    if (LangOpts.OpenMP >= 50)
6407
6.26k
      AllowedNameModifiers.push_back(OMPD_simd);
6408
8.98k
    break;
6409
90
  case OMPD_tile:
6410
90
    Res =
6411
90
        ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6412
90
    break;
6413
105
  case OMPD_unroll:
6414
105
    Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6415
105
                                     EndLoc);
6416
105
    break;
6417
10.5k
  case OMPD_for:
6418
10.5k
    Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6419
10.5k
                                  VarsWithInheritedDSA);
6420
10.5k
    break;
6421
8.02k
  case OMPD_for_simd:
6422
8.02k
    Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6423
8.02k
                                      EndLoc, VarsWithInheritedDSA);
6424
8.02k
    if (LangOpts.OpenMP >= 50)
6425
5.81k
      AllowedNameModifiers.push_back(OMPD_simd);
6426
8.02k
    break;
6427
6.04k
  case OMPD_sections:
6428
6.04k
    Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6429
6.04k
                                       EndLoc);
6430
6.04k
    break;
6431
1.39k
  case OMPD_section:
6432
1.39k
    assert(ClausesWithImplicit.empty() &&
6433
1.39k
           "No clauses are allowed for 'omp section' directive");
6434
1.39k
    Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6435
1.39k
    break;
6436
2.49k
  case OMPD_single:
6437
2.49k
    Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6438
2.49k
                                     EndLoc);
6439
2.49k
    break;
6440
1.67k
  case OMPD_master:
6441
1.67k
    assert(ClausesWithImplicit.empty() &&
6442
1.67k
           "No clauses are allowed for 'omp master' directive");
6443
1.67k
    Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6444
1.67k
    break;
6445
130
  case OMPD_masked:
6446
130
    Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6447
130
                                     EndLoc);
6448
130
    break;
6449
2.38k
  case OMPD_critical:
6450
2.38k
    Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6451
2.38k
                                       StartLoc, EndLoc);
6452
2.38k
    break;
6453
7.71k
  case OMPD_parallel_for:
6454
7.71k
    Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6455
7.71k
                                          EndLoc, VarsWithInheritedDSA);
6456
7.71k
    AllowedNameModifiers.push_back(OMPD_parallel);
6457
7.71k
    break;
6458
8.54k
  case OMPD_parallel_for_simd:
6459
8.54k
    Res = ActOnOpenMPParallelForSimdDirective(
6460
8.54k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6461
8.54k
    AllowedNameModifiers.push_back(OMPD_parallel);
6462
8.54k
    if (LangOpts.OpenMP >= 50)
6463
6.10k
      AllowedNameModifiers.push_back(OMPD_simd);
6464
8.54k
    break;
6465
1.16k
  case OMPD_scope:
6466
1.16k
    Res =
6467
1.16k
        ActOnOpenMPScopeDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6468
1.16k
    break;
6469
5.19k
  case OMPD_parallel_master:
6470
5.19k
    Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6471
5.19k
                                             StartLoc, EndLoc);
6472
5.19k
    AllowedNameModifiers.push_back(OMPD_parallel);
6473
5.19k
    break;
6474
3.74k
  case OMPD_parallel_masked:
6475
3.74k
    Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6476
3.74k
                                             StartLoc, EndLoc);
6477
3.74k
    AllowedNameModifiers.push_back(OMPD_parallel);
6478
3.74k
    break;
6479
5.44k
  case OMPD_parallel_sections:
6480
5.44k
    Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6481
5.44k
                                               StartLoc, EndLoc);
6482
5.44k
    AllowedNameModifiers.push_back(OMPD_parallel);
6483
5.44k
    break;
6484
5.44k
  case OMPD_task:
6485
5.44k
    Res =
6486
5.44k
        ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6487
5.44k
    AllowedNameModifiers.push_back(OMPD_task);
6488
5.44k
    break;
6489
855
  case OMPD_taskyield:
6490
855
    assert(ClausesWithImplicit.empty() &&
6491
855
           "No clauses are allowed for 'omp taskyield' directive");
6492
855
    assert(AStmt == nullptr &&
6493
855
           "No associated statement allowed for 'omp taskyield' directive");
6494
855
    Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6495
855
    break;
6496
160
  case OMPD_error:
6497
160
    assert(AStmt == nullptr &&
6498
160
           "No associated statement allowed for 'omp error' directive");
6499
160
    Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
6500
160
    break;
6501
443
  case OMPD_barrier:
6502
443
    assert(ClausesWithImplicit.empty() &&
6503
443
           "No clauses are allowed for 'omp barrier' directive");
6504
443
    assert(AStmt == nullptr &&
6505
443
           "No associated statement allowed for 'omp barrier' directive");
6506
443
    Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6507
443
    break;
6508
1.03k
  case OMPD_taskwait:
6509
1.03k
    assert(AStmt == nullptr &&
6510
1.03k
           "No associated statement allowed for 'omp taskwait' directive");
6511
1.03k
    Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6512
1.03k
    break;
6513
8.60k
  case OMPD_taskgroup:
6514
8.60k
    Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6515
8.60k
                                        EndLoc);
6516
8.60k
    break;
6517
1.15k
  case OMPD_flush:
6518
1.15k
    assert(AStmt == nullptr &&
6519
1.15k
           "No associated statement allowed for 'omp flush' directive");
6520
1.15k
    Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6521
1.15k
    break;
6522
648
  case OMPD_depobj:
6523
648
    assert(AStmt == nullptr &&
6524
648
           "No associated statement allowed for 'omp depobj' directive");
6525
648
    Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6526
648
    break;
6527
285
  case OMPD_scan:
6528
285
    assert(AStmt == nullptr &&
6529
285
           "No associated statement allowed for 'omp scan' directive");
6530
285
    Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6531
285
    break;
6532
2.24k
  case OMPD_ordered:
6533
2.24k
    Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6534
2.24k
                                      EndLoc);
6535
2.24k
    break;
6536
20.4k
  case OMPD_atomic:
6537
20.4k
    Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6538
20.4k
                                     EndLoc);
6539
20.4k
    break;
6540
27.2k
  case OMPD_teams:
6541
27.2k
    Res =
6542
27.2k
        ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6543
27.2k
    break;
6544
75.3k
  case OMPD_target:
6545
75.3k
    Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6546
75.3k
                                     EndLoc);
6547
75.3k
    AllowedNameModifiers.push_back(OMPD_target);
6548
75.3k
    break;
6549
9.87k
  case OMPD_target_parallel:
6550
9.87k
    Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6551
9.87k
                                             StartLoc, EndLoc);
6552
9.87k
    AllowedNameModifiers.push_back(OMPD_target);
6553
9.87k
    AllowedNameModifiers.push_back(OMPD_parallel);
6554
9.87k
    break;
6555
10.5k
  case OMPD_target_parallel_for:
6556
10.5k
    Res = ActOnOpenMPTargetParallelForDirective(
6557
10.5k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6558
10.5k
    AllowedNameModifiers.push_back(OMPD_target);
6559
10.5k
    AllowedNameModifiers.push_back(OMPD_parallel);
6560
10.5k
    break;
6561
253
  case OMPD_cancellation_point:
6562
253
    assert(ClausesWithImplicit.empty() &&
6563
253
           "No clauses are allowed for 'omp cancellation point' directive");
6564
253
    assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6565
253
                               "cancellation point' directive");
6566
253
    Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6567
253
    break;
6568
712
  case OMPD_cancel:
6569
712
    assert(AStmt == nullptr &&
6570
712
           "No associated statement allowed for 'omp cancel' directive");
6571
712
    Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6572
712
                                     CancelRegion);
6573
712
    AllowedNameModifiers.push_back(OMPD_cancel);
6574
712
    break;
6575
5.93k
  case OMPD_target_data:
6576
5.93k
    Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6577
5.93k
                                         EndLoc);
6578
5.93k
    AllowedNameModifiers.push_back(OMPD_target_data);
6579
5.93k
    break;
6580
2.36k
  case OMPD_target_enter_data:
6581
2.36k
    Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6582
2.36k
                                              EndLoc, AStmt);
6583
2.36k
    AllowedNameModifiers.push_back(OMPD_target_enter_data);
6584
2.36k
    break;
6585
2.34k
  case OMPD_target_exit_data:
6586
2.34k
    Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6587
2.34k
                                             EndLoc, AStmt);
6588
2.34k
    AllowedNameModifiers.push_back(OMPD_target_exit_data);
6589
2.34k
    break;
6590
8.96k
  case OMPD_taskloop:
6591
8.96k
    Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6592
8.96k
                                       EndLoc, VarsWithInheritedDSA);
6593
8.96k
    AllowedNameModifiers.push_back(OMPD_taskloop);
6594
8.96k
    break;
6595
7.68k
  case OMPD_taskloop_simd:
6596
7.68k
    Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6597
7.68k
                                           EndLoc, VarsWithInheritedDSA);
6598
7.68k
    AllowedNameModifiers.push_back(OMPD_taskloop);
6599
7.68k
    if (LangOpts.OpenMP >= 50)
6600
6.51k
      AllowedNameModifiers.push_back(OMPD_simd);
6601
7.68k
    break;
6602
6.42k
  case OMPD_master_taskloop:
6603
6.42k
    Res = ActOnOpenMPMasterTaskLoopDirective(
6604
6.42k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6605
6.42k
    AllowedNameModifiers.push_back(OMPD_taskloop);
6606
6.42k
    break;
6607
3.53k
  case OMPD_masked_taskloop:
6608
3.53k
    Res = ActOnOpenMPMaskedTaskLoopDirective(
6609
3.53k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6610
3.53k
    AllowedNameModifiers.push_back(OMPD_taskloop);
6611
3.53k
    break;
6612
7.50k
  case OMPD_master_taskloop_simd:
6613
7.50k
    Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6614
7.50k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6615
7.50k
    AllowedNameModifiers.push_back(OMPD_taskloop);
6616
7.50k
    if (LangOpts.OpenMP >= 50)
6617
6.34k
      AllowedNameModifiers.push_back(OMPD_simd);
6618
7.50k
    break;
6619
6.65k
  case OMPD_masked_taskloop_simd:
6620
6.65k
    Res = ActOnOpenMPMaskedTaskLoopSimdDirective(
6621
6.65k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6622
6.65k
    if (LangOpts.OpenMP >= 51) {
6623
5.65k
      AllowedNameModifiers.push_back(OMPD_taskloop);
6624
5.65k
      AllowedNameModifiers.push_back(OMPD_simd);
6625
5.65k
    }
6626
6.65k
    break;
6627
4.47k
  case OMPD_parallel_master_taskloop:
6628
4.47k
    Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6629
4.47k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6630
4.47k
    AllowedNameModifiers.push_back(OMPD_taskloop);
6631
4.47k
    AllowedNameModifiers.push_back(OMPD_parallel);
6632
4.47k
    break;
6633
4.15k
  case OMPD_parallel_masked_taskloop:
6634
4.15k
    Res = ActOnOpenMPParallelMaskedTaskLoopDirective(
6635
4.15k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6636
4.15k
    if (LangOpts.OpenMP >= 51) {
6637
3.14k
      AllowedNameModifiers.push_back(OMPD_taskloop);
6638
3.14k
      AllowedNameModifiers.push_back(OMPD_parallel);
6639
3.14k
    }
6640
4.15k
    break;
6641
5.56k
  case OMPD_parallel_master_taskloop_simd:
6642
5.56k
    Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6643
5.56k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6644
5.56k
    AllowedNameModifiers.push_back(OMPD_taskloop);
6645
5.56k
    AllowedNameModifiers.push_back(OMPD_parallel);
6646
5.56k
    if (LangOpts.OpenMP >= 50)
6647
4.40k
      AllowedNameModifiers.push_back(OMPD_simd);
6648
5.56k
    break;
6649
5.12k
  case OMPD_parallel_masked_taskloop_simd:
6650
5.12k
    Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6651
5.12k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6652
5.12k
    if (LangOpts.OpenMP >= 51) {
6653
4.11k
      AllowedNameModifiers.push_back(OMPD_taskloop);
6654
4.11k
      AllowedNameModifiers.push_back(OMPD_parallel);
6655
4.11k
      AllowedNameModifiers.push_back(OMPD_simd);
6656
4.11k
    }
6657
5.12k
    break;
6658
2.13k
  case OMPD_distribute:
6659
2.13k
    Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6660
2.13k
                                         EndLoc, VarsWithInheritedDSA);
6661
2.13k
    break;
6662
4.26k
  case OMPD_target_update:
6663
4.26k
    Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6664
4.26k
                                           EndLoc, AStmt);
6665
4.26k
    AllowedNameModifiers.push_back(OMPD_target_update);
6666
4.26k
    break;
6667
6.71k
  case OMPD_distribute_parallel_for:
6668
6.71k
    Res = ActOnOpenMPDistributeParallelForDirective(
6669
6.71k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6670
6.71k
    AllowedNameModifiers.push_back(OMPD_parallel);
6671
6.71k
    break;
6672
8.35k
  case OMPD_distribute_parallel_for_simd:
6673
8.35k
    Res = ActOnOpenMPDistributeParallelForSimdDirective(
6674
8.35k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6675
8.35k
    AllowedNameModifiers.push_back(OMPD_parallel);
6676
8.35k
    if (LangOpts.OpenMP >= 50)
6677
5.91k
      AllowedNameModifiers.push_back(OMPD_simd);
6678
8.35k
    break;
6679
6.79k
  case OMPD_distribute_simd:
6680
6.79k
    Res = ActOnOpenMPDistributeSimdDirective(
6681
6.79k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6682
6.79k
    if (LangOpts.OpenMP >= 50)
6683
5.07k
      AllowedNameModifiers.push_back(OMPD_simd);
6684
6.79k
    break;
6685
10.5k
  case OMPD_target_parallel_for_simd:
6686
10.5k
    Res = ActOnOpenMPTargetParallelForSimdDirective(
6687
10.5k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6688
10.5k
    AllowedNameModifiers.push_back(OMPD_target);
6689
10.5k
    AllowedNameModifiers.push_back(OMPD_parallel);
6690
10.5k
    if (LangOpts.OpenMP >= 50)
6691
7.73k
      AllowedNameModifiers.push_back(OMPD_simd);
6692
10.5k
    break;
6693
11.1k
  case OMPD_target_simd:
6694
11.1k
    Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6695
11.1k
                                         EndLoc, VarsWithInheritedDSA);
6696
11.1k
    AllowedNameModifiers.push_back(OMPD_target);
6697
11.1k
    if (LangOpts.OpenMP >= 50)
6698
7.83k
      AllowedNameModifiers.push_back(OMPD_simd);
6699
11.1k
    break;
6700
6.10k
  case OMPD_teams_distribute:
6701
6.10k
    Res = ActOnOpenMPTeamsDistributeDirective(
6702
6.10k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6703
6.10k
    break;
6704
6.78k
  case OMPD_teams_distribute_simd:
6705
6.78k
    Res = ActOnOpenMPTeamsDistributeSimdDirective(
6706
6.78k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6707
6.78k
    if (LangOpts.OpenMP >= 50)
6708
5.13k
      AllowedNameModifiers.push_back(OMPD_simd);
6709
6.78k
    break;
6710
7.65k
  case OMPD_teams_distribute_parallel_for_simd:
6711
7.65k
    Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6712
7.65k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6713
7.65k
    AllowedNameModifiers.push_back(OMPD_parallel);
6714
7.65k
    if (LangOpts.OpenMP >= 50)
6715
5.63k
      AllowedNameModifiers.push_back(OMPD_simd);
6716
7.65k
    break;
6717
6.61k
  case OMPD_teams_distribute_parallel_for:
6718
6.61k
    Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6719
6.61k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6720
6.61k
    AllowedNameModifiers.push_back(OMPD_parallel);
6721
6.61k
    break;
6722
9.89k
  case OMPD_target_teams:
6723
9.89k
    Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6724
9.89k
                                          EndLoc);
6725
9.89k
    AllowedNameModifiers.push_back(OMPD_target);
6726
9.89k
    break;
6727
9.39k
  case OMPD_target_teams_distribute:
6728
9.39k
    Res = ActOnOpenMPTargetTeamsDistributeDirective(
6729
9.39k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6730
9.39k
    AllowedNameModifiers.push_back(OMPD_target);
6731
9.39k
    break;
6732
9.46k
  case OMPD_target_teams_distribute_parallel_for:
6733
9.46k
    Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6734
9.46k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6735
9.46k
    AllowedNameModifiers.push_back(OMPD_target);
6736
9.46k
    AllowedNameModifiers.push_back(OMPD_parallel);
6737
9.46k
    break;
6738
11.8k
  case OMPD_target_teams_distribute_parallel_for_simd:
6739
11.8k
    Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6740
11.8k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6741
11.8k
    AllowedNameModifiers.push_back(OMPD_target);
6742
11.8k
    AllowedNameModifiers.push_back(OMPD_parallel);
6743
11.8k
    if (LangOpts.OpenMP >= 50)
6744
8.53k
      AllowedNameModifiers.push_back(OMPD_simd);
6745
11.8k
    break;
6746
11.1k
  case OMPD_target_teams_distribute_simd:
6747
11.1k
    Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6748
11.1k
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6749
11.1k
    AllowedNameModifiers.push_back(OMPD_target);
6750
11.1k
    if (LangOpts.OpenMP >= 50)
6751
7.81k
      AllowedNameModifiers.push_back(OMPD_simd);
6752
11.1k
    break;
6753
218
  case OMPD_interop:
6754
218
    assert(AStmt == nullptr &&
6755
218
           "No associated statement allowed for 'omp interop' directive");
6756
218
    Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6757
218
    break;
6758
150
  case OMPD_dispatch:
6759
150
    Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6760
150
                                       EndLoc);
6761
150
    break;
6762
0
  case OMPD_loop:
6763
0
    Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6764
0
                                          EndLoc, VarsWithInheritedDSA);
6765
0
    break;
6766
211
  case OMPD_teams_loop:
6767
211
    Res = ActOnOpenMPTeamsGenericLoopDirective(
6768
211
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6769
211
    break;
6770
523
  case OMPD_target_teams_loop:
6771
523
    Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6772
523
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6773
523
    AllowedNameModifiers.push_back(OMPD_target);
6774
523
    break;
6775
49
  case OMPD_parallel_loop:
6776
49
    Res = ActOnOpenMPParallelGenericLoopDirective(
6777
49
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6778
49
    break;
6779
871
  case OMPD_target_parallel_loop:
6780
871
    Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6781
871
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6782
871
    break;
6783
0
  case OMPD_declare_target:
6784
0
  case OMPD_end_declare_target:
6785
0
  case OMPD_threadprivate:
6786
0
  case OMPD_allocate:
6787
0
  case OMPD_declare_reduction:
6788
0
  case OMPD_declare_mapper:
6789
0
  case OMPD_declare_simd:
6790
0
  case OMPD_requires:
6791
0
  case OMPD_declare_variant:
6792
0
  case OMPD_begin_declare_variant:
6793
0
  case OMPD_end_declare_variant:
6794
0
    llvm_unreachable("OpenMP Directive is not allowed");
6795
0
  case OMPD_unknown:
6796
0
  default:
6797
0
    llvm_unreachable("Unknown OpenMP directive");
6798
484k
  }
6799
6800
484k
  ErrorFound = Res.isInvalid() || 
ErrorFound463k
;
6801
6802
  // Check variables in the clauses if default(none) or
6803
  // default(firstprivate) was specified.
6804
484k
  if (DSAStack->getDefaultDSA() == DSA_none ||
6805
484k
      
DSAStack482k
->getDefaultDSA() == DSA_private482k
||
6806
484k
      
DSAStack482k
->getDefaultDSA() == DSA_firstprivate482k
) {
6807
1.60k
    DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6808
6.99k
    for (OMPClause *C : Clauses) {
6809
6.99k
      switch (C->getClauseKind()) {
6810
187
      case OMPC_num_threads:
6811
295
      case OMPC_dist_schedule:
6812
        // Do not analyse if no parent teams directive.
6813
295
        if (isOpenMPTeamsDirective(Kind))
6814
0
          break;
6815
295
        continue;
6816
310
      case OMPC_if:
6817
310
        if (isOpenMPTeamsDirective(Kind) &&
6818
310
            
cast<OMPIfClause>(C)->getNameModifier() != OMPD_target4
)
6819
4
          break;
6820
306
        if (isOpenMPParallelDirective(Kind) &&
6821
306
            
isOpenMPTaskLoopDirective(Kind)254
&&
6822
306
            
cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel68
)
6823
32
          break;
6824
274
        continue;
6825
274
      case OMPC_schedule:
6826
258
      case OMPC_detach:
6827
258
        break;
6828
0
      case OMPC_grainsize:
6829
56
      case OMPC_num_tasks:
6830
128
      case OMPC_final:
6831
200
      case OMPC_priority:
6832
200
      case OMPC_novariants:
6833
200
      case OMPC_nocontext:
6834
        // Do not analyze if no parent parallel directive.
6835
200
        if (isOpenMPParallelDirective(Kind))
6836
60
          break;
6837
140
        continue;
6838
140
      case OMPC_ordered:
6839
0
      case OMPC_device:
6840
262
      case OMPC_num_teams:
6841
524
      case OMPC_thread_limit:
6842
524
      case OMPC_hint:
6843
524
      case OMPC_collapse:
6844
548
      case OMPC_safelen:
6845
548
      case OMPC_simdlen:
6846
548
      case OMPC_sizes:
6847
2.15k
      case OMPC_default:
6848
2.33k
      case OMPC_proc_bind:
6849
2.86k
      case OMPC_private:
6850
3.40k
      case OMPC_firstprivate:
6851
3.44k
      case OMPC_lastprivate:
6852
4.04k
      case OMPC_shared:
6853
4.99k
      case OMPC_reduction:
6854
4.99k
      case OMPC_task_reduction:
6855
5.03k
      case OMPC_in_reduction:
6856
5.20k
      case OMPC_linear:
6857
5.23k
      case OMPC_aligned:
6858
5.52k
      case OMPC_copyin:
6859
5.52k
      case OMPC_copyprivate:
6860
5.52k
      case OMPC_nowait:
6861
5.52k
      case OMPC_untied:
6862
5.52k
      case OMPC_mergeable:
6863
5.79k
      case OMPC_allocate:
6864
5.79k
      case OMPC_read:
6865
5.79k
      case OMPC_write:
6866
5.79k
      case OMPC_update:
6867
5.79k
      case OMPC_capture:
6868
5.79k
      case OMPC_compare:
6869
5.79k
      case OMPC_seq_cst:
6870
5.79k
      case OMPC_acq_rel:
6871
5.79k
      case OMPC_acquire:
6872
5.79k
      case OMPC_release:
6873
5.79k
      case OMPC_relaxed:
6874
5.79k
      case OMPC_depend:
6875
5.79k
      case OMPC_threads:
6876
5.79k
      case OMPC_simd:
6877
5.80k
      case OMPC_map:
6878
5.80k
      case OMPC_nogroup:
6879
5.80k
      case OMPC_defaultmap:
6880
5.80k
      case OMPC_to:
6881
5.80k
      case OMPC_from:
6882
5.80k
      case OMPC_use_device_ptr:
6883
5.80k
      case OMPC_use_device_addr:
6884
5.80k
      case OMPC_is_device_ptr:
6885
5.80k
      case OMPC_has_device_addr:
6886
5.80k
      case OMPC_nontemporal:
6887
5.87k
      case OMPC_order:
6888
5.87k
      case OMPC_destroy:
6889
5.87k
      case OMPC_inclusive:
6890
5.87k
      case OMPC_exclusive:
6891
5.88k
      case OMPC_uses_allocators:
6892
5.89k
      case OMPC_affinity:
6893
5.90k
      case OMPC_bind:
6894
5.92k
      case OMPC_filter:
6895
5.92k
        continue;
6896
0
      case OMPC_allocator:
6897
0
      case OMPC_flush:
6898
0
      case OMPC_depobj:
6899
0
      case OMPC_threadprivate:
6900
0
      case OMPC_uniform:
6901
0
      case OMPC_unknown:
6902
0
      case OMPC_unified_address:
6903
0
      case OMPC_unified_shared_memory:
6904
0
      case OMPC_reverse_offload:
6905
0
      case OMPC_dynamic_allocators:
6906
0
      case OMPC_atomic_default_mem_order:
6907
0
      case OMPC_device_type:
6908
0
      case OMPC_match:
6909
0
      case OMPC_when:
6910
0
      case OMPC_at:
6911
0
      case OMPC_severity:
6912
0
      case OMPC_message:
6913
0
      default:
6914
0
        llvm_unreachable("Unexpected clause");
6915
6.99k
      }
6916
354
      for (Stmt *CC : C->children()) {
6917
354
        if (CC)
6918
190
          DSAChecker.Visit(CC);
6919
354
      }
6920
354
    }
6921
1.60k
    for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6922
48
      VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6923
1.60k
  }
6924
484k
  for (const auto &P : VarsWithInheritedDSA) {
6925
630
    if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6926
0
      continue;
6927
630
    ErrorFound = true;
6928
630
    if (DSAStack->getDefaultDSA() == DSA_none ||
6929
630
        
DSAStack190
->getDefaultDSA() == DSA_private190
||
6930
630
        
DSAStack138
->getDefaultDSA() == DSA_firstprivate138
) {
6931
552
      Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6932
552
          << P.first << P.second->getSourceRange();
6933
552
      Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6934
552
    } else 
if (78
getLangOpts().OpenMP >= 5078
) {
6935
78
      Diag(P.second->getExprLoc(),
6936
78
           diag::err_omp_defaultmap_no_attr_for_variable)
6937
78
          << P.first << P.second->getSourceRange();
6938
78
      Diag(DSAStack->getDefaultDSALocation(),
6939
78
           diag::note_omp_defaultmap_attr_none);
6940
78
    }
6941
630
  }
6942
6943
484k
  if (!AllowedNameModifiers.empty())
6944
373k
    ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6945
373k
                 
ErrorFound372k
;
6946
6947
484k
  if (ErrorFound)
6948
22.4k
    return StmtError();
6949
6950
461k
  if (!CurContext->isDependentContext() &&
6951
461k
      
isOpenMPTargetExecutionDirective(Kind)338k
&&
6952
461k
      
!(120k
DSAStack120k
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>()120k
||
6953
120k
        
DSAStack120k
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>()120k
||
6954
120k
        
DSAStack120k
->hasRequiresDeclWithClause<OMPReverseOffloadClause>()120k
||
6955
120k
        
DSAStack120k
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()120k
)) {
6956
    // Register target to DSA Stack.
6957
111k
    DSAStack->addTargetDirLocation(StartLoc);
6958
111k
  }
6959
6960
461k
  return Res;
6961
484k
}
6962
6963
Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6964
    DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6965
    ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6966
    ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6967
544
    ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6968
544
  assert(Aligneds.size() == Alignments.size());
6969
544
  assert(Linears.size() == LinModifiers.size());
6970
544
  assert(Linears.size() == Steps.size());
6971
544
  if (!DG || DG.get().isNull())
6972
0
    return DeclGroupPtrTy();
6973
6974
544
  const int SimdId = 0;
6975
544
  if (!DG.get().isSingleDecl()) {
6976
2
    Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6977
2
        << SimdId;
6978
2
    return DG;
6979
2
  }
6980
542
  Decl *ADecl = DG.get().getSingleDecl();
6981
542
  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6982
34
    ADecl = FTD->getTemplatedDecl();
6983
6984
542
  auto *FD = dyn_cast<FunctionDecl>(ADecl);
6985
542
  if (!FD) {
6986
4
    Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6987
4
    return DeclGroupPtrTy();
6988
4
  }
6989
6990
  // OpenMP [2.8.2, declare simd construct, Description]
6991
  // The parameter of the simdlen clause must be a constant positive integer
6992
  // expression.
6993
538
  ExprResult SL;
6994
538
  if (Simdlen)
6995
168
    SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6996
  // OpenMP [2.8.2, declare simd construct, Description]
6997
  // The special this pointer can be used as if was one of the arguments to the
6998
  // function in any of the linear, aligned, or uniform clauses.
6999
  // The uniform clause declares one or more arguments to have an invariant
7000
  // value for all concurrent invocations of the function in the execution of a
7001
  // single SIMD loop.
7002
538
  llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
7003
538
  const Expr *UniformedLinearThis = nullptr;
7004
538
  for (const Expr *E : Uniforms) {
7005
98
    E = E->IgnoreParenImpCasts();
7006
98
    if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7007
72
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
7008
68
        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7009
68
            FD->getParamDecl(PVD->getFunctionScopeIndex())
7010
68
                    ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
7011
68
          UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
7012
68
          continue;
7013
68
        }
7014
30
    if (isa<CXXThisExpr>(E)) {
7015
26
      UniformedLinearThis = E;
7016
26
      continue;
7017
26
    }
7018
4
    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7019
4
        << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 
10
: 0);
7020
4
  }
7021
  // OpenMP [2.8.2, declare simd construct, Description]
7022
  // The aligned clause declares that the object to which each list item points
7023
  // is aligned to the number of bytes expressed in the optional parameter of
7024
  // the aligned clause.
7025
  // The special this pointer can be used as if was one of the arguments to the
7026
  // function in any of the linear, aligned, or uniform clauses.
7027
  // The type of list items appearing in the aligned clause must be array,
7028
  // pointer, reference to array, or reference to pointer.
7029
538
  llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
7030
538
  const Expr *AlignedThis = nullptr;
7031
538
  for (const Expr *E : Aligneds) {
7032
210
    E = E->IgnoreParenImpCasts();
7033
210
    if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7034
206
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7035
202
        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7036
202
        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7037
202
            FD->getParamDecl(PVD->getFunctionScopeIndex())
7038
202
                    ->getCanonicalDecl() == CanonPVD) {
7039
          // OpenMP  [2.8.1, simd construct, Restrictions]
7040
          // A list-item cannot appear in more than one aligned clause.
7041
202
          if (AlignedArgs.count(CanonPVD) > 0) {
7042
4
            Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
7043
4
                << 1 << getOpenMPClauseName(OMPC_aligned)
7044
4
                << E->getSourceRange();
7045
4
            Diag(AlignedArgs[CanonPVD]->getExprLoc(),
7046
4
                 diag::note_omp_explicit_dsa)
7047
4
                << getOpenMPClauseName(OMPC_aligned);
7048
4
            continue;
7049
4
          }
7050
198
          AlignedArgs[CanonPVD] = E;
7051
198
          QualType QTy = PVD->getType()
7052
198
                             .getNonReferenceType()
7053
198
                             .getUnqualifiedType()
7054
198
                             .getCanonicalType();
7055
198
          const Type *Ty = QTy.getTypePtrOrNull();
7056
198
          if (!Ty || (!Ty->isArrayType() && 
!Ty->isPointerType()174
)) {
7057
4
            Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
7058
4
                << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
7059
4
            Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
7060
4
          }
7061
198
          continue;
7062
202
        }
7063
202
      }
7064
8
    if (isa<CXXThisExpr>(E)) {
7065
4
      if (AlignedThis) {
7066
2
        Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
7067
2
            << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
7068
2
        Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
7069
2
            << getOpenMPClauseName(OMPC_aligned);
7070
2
      }
7071
4
      AlignedThis = E;
7072
4
      continue;
7073
4
    }
7074
4
    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7075
4
        << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 
10
: 0);
7076
4
  }
7077
  // The optional parameter of the aligned clause, alignment, must be a constant
7078
  // positive integer expression. If no optional parameter is specified,
7079
  // implementation-defined default alignments for SIMD instructions on the
7080
  // target platforms are assumed.
7081
538
  SmallVector<const Expr *, 4> NewAligns;
7082
538
  for (Expr *E : Alignments) {
7083
210
    ExprResult Align;
7084
210
    if (E)
7085
88
      Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
7086
210
    NewAligns.push_back(Align.get());
7087
210
  }
7088
  // OpenMP [2.8.2, declare simd construct, Description]
7089
  // The linear clause declares one or more list items to be private to a SIMD
7090
  // lane and to have a linear relationship with respect to the iteration space
7091
  // of a loop.
7092
  // The special this pointer can be used as if was one of the arguments to the
7093
  // function in any of the linear, aligned, or uniform clauses.
7094
  // When a linear-step expression is specified in a linear clause it must be
7095
  // either a constant integer expression or an integer-typed parameter that is
7096
  // specified in a uniform clause on the directive.
7097
538
  llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
7098
538
  const bool IsUniformedThis = UniformedLinearThis != nullptr;
7099
538
  auto MI = LinModifiers.begin();
7100
538
  for (const Expr *E : Linears) {
7101
326
    auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
7102
326
    ++MI;
7103
326
    E = E->IgnoreParenImpCasts();
7104
326
    if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7105
316
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7106
316
        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7107
316
        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7108
316
            FD->getParamDecl(PVD->getFunctionScopeIndex())
7109
316
                    ->getCanonicalDecl() == CanonPVD) {
7110
          // OpenMP  [2.15.3.7, linear Clause, Restrictions]
7111
          // A list-item cannot appear in more than one linear clause.
7112
316
          if (LinearArgs.count(CanonPVD) > 0) {
7113
4
            Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7114
4
                << getOpenMPClauseName(OMPC_linear)
7115
4
                << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
7116
4
            Diag(LinearArgs[CanonPVD]->getExprLoc(),
7117
4
                 diag::note_omp_explicit_dsa)
7118
4
                << getOpenMPClauseName(OMPC_linear);
7119
4
            continue;
7120
4
          }
7121
          // Each argument can appear in at most one uniform or linear clause.
7122
312
          if (UniformedArgs.count(CanonPVD) > 0) {
7123
4
            Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7124
4
                << getOpenMPClauseName(OMPC_linear)
7125
4
                << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
7126
4
            Diag(UniformedArgs[CanonPVD]->getExprLoc(),
7127
4
                 diag::note_omp_explicit_dsa)
7128
4
                << getOpenMPClauseName(OMPC_uniform);
7129
4
            continue;
7130
4
          }
7131
308
          LinearArgs[CanonPVD] = E;
7132
308
          if (E->isValueDependent() || 
E->isTypeDependent()292
||
7133
308
              
E->isInstantiationDependent()292
||
7134
308
              
E->containsUnexpandedParameterPack()292
)
7135
16
            continue;
7136
292
          (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
7137
292
                                      PVD->getOriginalType(),
7138
292
                                      /*IsDeclareSimd=*/true);
7139
292
          continue;
7140
308
        }
7141
316
      }
7142
10
    if (isa<CXXThisExpr>(E)) {
7143
10
      if (UniformedLinearThis) {
7144
2
        Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7145
2
            << getOpenMPClauseName(OMPC_linear)
7146
2
            << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : 
OMPC_linear0
)
7147
2
            << E->getSourceRange();
7148
2
        Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
7149
2
            << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7150
2
                                                   : 
OMPC_linear0
);
7151
2
        continue;
7152
2
      }
7153
8
      UniformedLinearThis = E;
7154
8
      if (E->isValueDependent() || E->isTypeDependent() ||
7155
8
          E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
7156
0
        continue;
7157
8
      (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
7158
8
                                  E->getType(), /*IsDeclareSimd=*/true);
7159
8
      continue;
7160
8
    }
7161
0
    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7162
0
        << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7163
0
  }
7164
538
  Expr *Step = nullptr;
7165
538
  Expr *NewStep = nullptr;
7166
538
  SmallVector<Expr *, 4> NewSteps;
7167
538
  for (Expr *E : Steps) {
7168
    // Skip the same step expression, it was checked already.
7169
326
    if (Step == E || 
!E266
) {
7170
108
      NewSteps.push_back(E ? 
NewStep4
:
nullptr104
);
7171
108
      continue;
7172
108
    }
7173
218
    Step = E;
7174
218
    if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7175
62
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7176
38
        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7177
38
        if (UniformedArgs.count(CanonPVD) == 0) {
7178
4
          Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
7179
4
              << Step->getSourceRange();
7180
34
        } else if (E->isValueDependent() || E->isTypeDependent() ||
7181
34
                   E->isInstantiationDependent() ||
7182
34
                   E->containsUnexpandedParameterPack() ||
7183
34
                   CanonPVD->getType()->hasIntegerRepresentation()) {
7184
34
          NewSteps.push_back(Step);
7185
34
        } else {
7186
0
          Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
7187
0
              << Step->getSourceRange();
7188
0
        }
7189
38
        continue;
7190
38
      }
7191
180
    NewStep = Step;
7192
180
    if (Step && !Step->isValueDependent() && 
!Step->isTypeDependent()156
&&
7193
180
        
!Step->isInstantiationDependent()156
&&
7194
180
        
!Step->containsUnexpandedParameterPack()156
) {
7195
156
      NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
7196
156
                    .get();
7197
156
      if (NewStep)
7198
156
        NewStep =
7199
156
            VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
7200
156
    }
7201
180
    NewSteps.push_back(NewStep);
7202
180
  }
7203
538
  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7204
538
      Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
7205
538
      Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
7206
538
      const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
7207
538
      const_cast<Expr **>(Linears.data()), Linears.size(),
7208
538
      const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
7209
538
      NewSteps.data(), NewSteps.size(), SR);
7210
538
  ADecl->addAttr(NewAttr);
7211
538
  return DG;
7212
542
}
7213
7214
static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
7215
18
                         QualType NewType) {
7216
18
  assert(NewType->isFunctionProtoType() &&
7217
18
         "Expected function type with prototype.");
7218
18
  assert(FD->getType()->isFunctionNoProtoType() &&
7219
18
         "Expected function with type with no prototype.");
7220
18
  assert(FDWithProto->getType()->isFunctionProtoType() &&
7221
18
         "Expected function with prototype.");
7222
  // Synthesize parameters with the same types.
7223
18
  FD->setType(NewType);
7224
18
  SmallVector<ParmVarDecl *, 16> Params;
7225
18
  for (const ParmVarDecl *P : FDWithProto->parameters()) {
7226
18
    auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
7227
18
                                      SourceLocation(), nullptr, P->getType(),
7228
18
                                      /*TInfo=*/nullptr, SC_None, nullptr);
7229
18
    Param->setScopeInfo(0, Params.size());
7230
18
    Param->setImplicit();
7231
18
    Params.push_back(Param);
7232
18
  }
7233
7234
18
  FD->setParams(Params);
7235
18
}
7236
7237
176k
void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
7238
176k
  if (D->isInvalidDecl())
7239
0
    return;
7240
176k
  FunctionDecl *FD = nullptr;
7241
176k
  if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7242
0
    FD = UTemplDecl->getTemplatedDecl();
7243
176k
  else
7244
176k
    FD = cast<FunctionDecl>(D);
7245
176k
  assert(FD && "Expected a function declaration!");
7246
7247
  // If we are instantiating templates we do *not* apply scoped assumptions but
7248
  // only global ones. We apply scoped assumption to the template definition
7249
  // though.
7250
176k
  if (!inTemplateInstantiation()) {
7251
155k
    for (AssumptionAttr *AA : OMPAssumeScoped)
7252
4.35k
      FD->addAttr(AA);
7253
155k
  }
7254
176k
  for (AssumptionAttr *AA : OMPAssumeGlobal)
7255
309
    FD->addAttr(AA);
7256
176k
}
7257
7258
Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
7259
383
    : TI(&TI), NameSuffix(TI.getMangledName()) {}
7260
7261
void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
7262
    Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
7263
8.77k
    SmallVectorImpl<FunctionDecl *> &Bases) {
7264
8.77k
  if (!D.getIdentifier())
7265
0
    return;
7266
7267
8.77k
  OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7268
7269
  // Template specialization is an extension, check if we do it.
7270
8.77k
  bool IsTemplated = !TemplateParamLists.empty();
7271
8.77k
  if (IsTemplated &
7272
8.77k
      !DVScope.TI->isExtensionActive(
7273
8.77k
          llvm::omp::TraitProperty::implementation_extension_allow_templates))
7274
16
    return;
7275
7276
8.75k
  IdentifierInfo *BaseII = D.getIdentifier();
7277
8.75k
  LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
7278
8.75k
                      LookupOrdinaryName);
7279
8.75k
  LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
7280
7281
8.75k
  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
7282
8.75k
  QualType FType = TInfo->getType();
7283
7284
8.75k
  bool IsConstexpr =
7285
8.75k
      D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
7286
8.75k
  bool IsConsteval =
7287
8.75k
      D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
7288
7289
8.75k
  for (auto *Candidate : Lookup) {
7290
4.96k
    auto *CandidateDecl = Candidate->getUnderlyingDecl();
7291
4.96k
    FunctionDecl *UDecl = nullptr;
7292
4.96k
    if (IsTemplated && 
isa<FunctionTemplateDecl>(CandidateDecl)77
) {
7293
34
      auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7294
34
      if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7295
30
        UDecl = FTD->getTemplatedDecl();
7296
4.92k
    } else if (!IsTemplated)
7297
4.88k
      UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7298
4.96k
    if (!UDecl)
7299
95
      continue;
7300
7301
    // Don't specialize constexpr/consteval functions with
7302
    // non-constexpr/consteval functions.
7303
4.86k
    if (UDecl->isConstexpr() && 
!IsConstexpr72
)
7304
0
      continue;
7305
4.86k
    if (UDecl->isConsteval() && 
!IsConsteval0
)
7306
0
      continue;
7307
7308
4.86k
    QualType UDeclTy = UDecl->getType();
7309
4.86k
    if (!UDeclTy->isDependentType()) {
7310
4.83k
      QualType NewType = Context.mergeFunctionTypes(
7311
4.83k
          FType, UDeclTy, /* OfBlockPointer */ false,
7312
4.83k
          /* Unqualified */ false, /* AllowCXX */ true);
7313
4.83k
      if (NewType.isNull())
7314
1.43k
        continue;
7315
4.83k
    }
7316
7317
    // Found a base!
7318
3.43k
    Bases.push_back(UDecl);
7319
3.43k
  }
7320
7321
8.75k
  bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7322
8.75k
      llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7323
  // If no base was found we create a declaration that we use as base.
7324
8.75k
  if (Bases.empty() && 
UseImplicitBase5.32k
) {
7325
5.24k
    D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
7326
5.24k
    Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
7327
5.24k
    BaseD->setImplicit(true);
7328
5.24k
    if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7329
13
      Bases.push_back(BaseTemplD->getTemplatedDecl());
7330
5.22k
    else
7331
5.22k
      Bases.push_back(cast<FunctionDecl>(BaseD));
7332
5.24k
  }
7333
7334
8.75k
  std::string MangledName;
7335
8.75k
  MangledName += D.getIdentifier()->getName();
7336
8.75k
  MangledName += getOpenMPVariantManglingSeparatorStr();
7337
8.75k
  MangledName += DVScope.NameSuffix;
7338
8.75k
  IdentifierInfo &VariantII = Context.Idents.get(MangledName);
7339
7340
8.75k
  VariantII.setMangledOpenMPVariantName(true);
7341
8.75k
  D.SetIdentifier(&VariantII, D.getBeginLoc());
7342
8.75k
}
7343
7344
void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
7345
8.67k
    Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
7346
  // Do not mark function as is used to prevent its emission if this is the
7347
  // only place where it is used.
7348
8.67k
  EnterExpressionEvaluationContext Unevaluated(
7349
8.67k
      *this, Sema::ExpressionEvaluationContext::Unevaluated);
7350
7351
8.67k
  FunctionDecl *FD = nullptr;
7352
8.67k
  if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7353
42
    FD = UTemplDecl->getTemplatedDecl();
7354
8.63k
  else
7355
8.63k
    FD = cast<FunctionDecl>(D);
7356
8.67k
  auto *VariantFuncRef = DeclRefExpr::Create(
7357
8.67k
      Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
7358
8.67k
      /* RefersToEnclosingVariableOrCapture */ false,
7359
8.67k
      /* NameLoc */ FD->getLocation(), FD->getType(),
7360
8.67k
      ExprValueKind::VK_PRValue);
7361
7362
8.67k
  OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7363
8.67k
  auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7364
8.67k
      Context, VariantFuncRef, DVScope.TI,
7365
8.67k
      /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7366
8.67k
      /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7367
8.67k
      /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7368
8.67k
  for (FunctionDecl *BaseFD : Bases)
7369
8.67k
    BaseFD->addAttr(OMPDeclareVariantA);
7370
8.67k
}
7371
7372
ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
7373
                                 SourceLocation LParenLoc,
7374
                                 MultiExprArg ArgExprs,
7375
227k
                                 SourceLocation RParenLoc, Expr *ExecConfig) {
7376
  // The common case is a regular call we do not want to specialize at all. Try
7377
  // to make that case fast by bailing early.
7378
227k
  CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7379
227k
  if (!CE)
7380
34
    return Call;
7381
7382
227k
  FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
7383
227k
  if (!CalleeFnDecl)
7384
2.30k
    return Call;
7385
7386
225k
  if (LangOpts.OpenMP >= 51 && 
CalleeFnDecl->getIdentifier()167k
&&
7387
225k
      
CalleeFnDecl->getName().starts_with_insensitive("omp_")165k
) {
7388
    // checking for any calls inside an Order region
7389
29
    if (Scope && 
Scope->isOpenMPOrderClauseScope()27
)
7390
8
      Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7391
29
  }
7392
7393
225k
  if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
7394
222k
    return Call;
7395
7396
2.79k
  ASTContext &Context = getASTContext();
7397
2.79k
  std::function<void(StringRef)> DiagUnknownTrait = [this,
7398
2.79k
                                                     CE](StringRef ISATrait) {
7399
    // TODO Track the selector locations in a way that is accessible here to
7400
    // improve the diagnostic location.
7401
8
    Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
7402
8
        << ISATrait;
7403
8
  };
7404
2.79k
  TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
7405
2.79k
                          getCurFunctionDecl(), DSAStack->getConstructTraits());
7406
7407
2.79k
  QualType CalleeFnType = CalleeFnDecl->getType();
7408
7409
2.79k
  SmallVector<Expr *, 4> Exprs;
7410
2.79k
  SmallVector<VariantMatchInfo, 4> VMIs;
7411
5.71k
  while (CalleeFnDecl) {
7412
2.92k
    for (OMPDeclareVariantAttr *A :
7413
3.25k
         CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
7414
3.25k
      Expr *VariantRef = A->getVariantFuncRef();
7415
7416
3.25k
      VariantMatchInfo VMI;
7417
3.25k
      OMPTraitInfo &TI = A->getTraitInfo();
7418
3.25k
      TI.getAsVariantMatchInfo(Context, VMI);
7419
3.25k
      if (!isVariantApplicableInContext(VMI, OMPCtx,
7420
3.25k
                                        /* DeviceSetOnly */ false))
7421
420
        continue;
7422
7423
2.83k
      VMIs.push_back(VMI);
7424
2.83k
      Exprs.push_back(VariantRef);
7425
2.83k
    }
7426
7427
2.92k
    CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
7428
2.92k
  }
7429
7430
2.79k
  ExprResult NewCall;
7431
2.79k
  do {
7432
2.79k
    int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7433
2.79k
    if (BestIdx < 0)
7434
238
      return Call;
7435
2.55k
    Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7436
2.55k
    Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7437
7438
2.55k
    {
7439
      // Try to build a (member) call expression for the current best applicable
7440
      // variant expression. We allow this to fail in which case we continue
7441
      // with the next best variant expression. The fail case is part of the
7442
      // implementation defined behavior in the OpenMP standard when it talks
7443
      // about what differences in the function prototypes: "Any differences
7444
      // that the specific OpenMP context requires in the prototype of the
7445
      // variant from the base function prototype are implementation defined."
7446
      // This wording is there to allow the specialized variant to have a
7447
      // different type than the base function. This is intended and OK but if
7448
      // we cannot create a call the difference is not in the "implementation
7449
      // defined range" we allow.
7450
2.55k
      Sema::TentativeAnalysisScope Trap(*this);
7451
7452
2.55k
      if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7453
128
        auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7454
128
        BestExpr = MemberExpr::CreateImplicit(
7455
128
            Context, MemberCall->getImplicitObjectArgument(),
7456
128
            /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
7457
128
            MemberCall->getValueKind(), MemberCall->getObjectKind());
7458
128
      }
7459
2.55k
      NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
7460
2.55k
                              ExecConfig);
7461
2.55k
      if (NewCall.isUsable()) {
7462
2.55k
        if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7463
2.55k
          FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7464
2.55k
          QualType NewType = Context.mergeFunctionTypes(
7465
2.55k
              CalleeFnType, NewCalleeFnDecl->getType(),
7466
2.55k
              /* OfBlockPointer */ false,
7467
2.55k
              /* Unqualified */ false, /* AllowCXX */ true);
7468
2.55k
          if (!NewType.isNull())
7469
2.55k
            break;
7470
          // Don't use the call if the function type was not compatible.
7471
0
          NewCall = nullptr;
7472
0
        }
7473
2.55k
      }
7474
2.55k
    }
7475
7476
0
    VMIs.erase(VMIs.begin() + BestIdx);
7477
0
    Exprs.erase(Exprs.begin() + BestIdx);
7478
0
  } while (!VMIs.empty());
7479
7480
2.55k
  if (!NewCall.isUsable())
7481
0
    return Call;
7482
2.55k
  return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7483
2.55k
}
7484
7485
std::optional<std::pair<FunctionDecl *, Expr *>>
7486
Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
7487
                                        Expr *VariantRef, OMPTraitInfo &TI,
7488
                                        unsigned NumAppendArgs,
7489
2.57k
                                        SourceRange SR) {
7490
2.57k
  if (!DG || DG.get().isNull())
7491
0
    return std::nullopt;
7492
7493
2.57k
  const int VariantId = 1;
7494
  // Must be applied only to single decl.
7495
2.57k
  if (!DG.get().isSingleDecl()) {
7496
8
    Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7497
8
        << VariantId << SR;
7498
8
    return std::nullopt;
7499
8
  }
7500
2.56k
  Decl *ADecl = DG.get().getSingleDecl();
7501
2.56k
  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7502
229
    ADecl = FTD->getTemplatedDecl();
7503
7504
  // Decl must be a function.
7505
2.56k
  auto *FD = dyn_cast<FunctionDecl>(ADecl);
7506
2.56k
  if (!FD) {
7507
16
    Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7508
16
        << VariantId << SR;
7509
16
    return std::nullopt;
7510
16
  }
7511
7512
2.55k
  auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7513
    // The 'target' attribute needs to be separately checked because it does
7514
    // not always signify a multiversion function declaration.
7515
2.55k
    return FD->isMultiVersion() || 
FD->hasAttr<TargetAttr>()2.53k
;
7516
2.55k
  };
7517
  // OpenMP is not compatible with multiversion function attributes.
7518
2.55k
  if (HasMultiVersionAttributes(FD)) {
7519
24
    Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7520
24
        << SR;
7521
24
    return std::nullopt;
7522
24
  }
7523
7524
  // Allow #pragma omp declare variant only if the function is not used.
7525
2.52k
  if (FD->isUsed(false))
7526
8
    Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7527
8
        << FD->getLocation();
7528
7529
  // Check if the function was emitted already.
7530
2.52k
  const FunctionDecl *Definition;
7531
2.52k
  if (!FD->isThisDeclarationADefinition() && 
FD->isDefined(Definition)1.07k
&&
7532
2.52k
      
(8
LangOpts.EmitAllDecls8
||
Context.DeclMustBeEmitted(Definition)8
))
7533
8
    Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7534
8
        << FD->getLocation();
7535
7536
  // The VariantRef must point to function.
7537
2.52k
  if (!VariantRef) {
7538
0
    Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7539
0
    return std::nullopt;
7540
0
  }
7541
7542
4.54k
  
auto ShouldDelayChecks = [](Expr *&E, bool) 2.52k
{
7543
4.54k
    return E && 
(2.48k
E->isTypeDependent()2.48k
||
E->isValueDependent()2.43k
||
7544
2.48k
                 
E->containsUnexpandedParameterPack()2.43k
||
7545
2.48k
                 
E->isInstantiationDependent()2.43k
);
7546
4.54k
  };
7547
  // Do not check templates, wait until instantiation.
7548
2.52k
  if (FD->isDependentContext() || 
ShouldDelayChecks(VariantRef, false)2.29k
||
7549
2.52k
      
TI.anyScoreOrCondition(ShouldDelayChecks)2.25k
)
7550
277
    return std::make_pair(FD, VariantRef);
7551
7552
  // Deal with non-constant score and user condition expressions.
7553
2.25k
  auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7554
2.25k
                                                     bool IsScore) -> bool {
7555
2.24k
    if (!E || 
E->isIntegerConstantExpr(Context)182
)
7556
2.19k
      return false;
7557
7558
56
    if (IsScore) {
7559
      // We warn on non-constant scores and pretend they were not present.
7560
32
      Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7561
32
          << E;
7562
32
      E = nullptr;
7563
32
    } else {
7564
      // We could replace a non-constant user condition with "false" but we
7565
      // will soon need to handle these anyway for the dynamic version of
7566
      // OpenMP context selectors.
7567
24
      Diag(E->getExprLoc(),
7568
24
           diag::err_omp_declare_variant_user_condition_not_constant)
7569
24
          << E;
7570
24
    }
7571
56
    return true;
7572
2.24k
  };
7573
2.25k
  if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7574
56
    return std::nullopt;
7575
7576
2.19k
  QualType AdjustedFnType = FD->getType();
7577
2.19k
  if (NumAppendArgs) {
7578
106
    const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7579
106
    if (!PTy) {
7580
3
      Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7581
3
          << SR;
7582
3
      return std::nullopt;
7583
3
    }
7584
    // Adjust the function type to account for an extra omp_interop_t for each
7585
    // specified in the append_args clause.
7586
103
    const TypeDecl *TD = nullptr;
7587
103
    LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7588
103
                        SR.getBegin(), Sema::LookupOrdinaryName);
7589
103
    if (LookupName(Result, getCurScope())) {
7590
102
      NamedDecl *ND = Result.getFoundDecl();
7591
102
      TD = dyn_cast_or_null<TypeDecl>(ND);
7592
102
    }
7593
103
    if (!TD) {
7594
1
      Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7595
1
      return std::nullopt;
7596
1
    }
7597
102
    QualType InteropType = Context.getTypeDeclType(TD);
7598
102
    if (PTy->isVariadic()) {
7599
4
      Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7600
4
      return std::nullopt;
7601
4
    }
7602
98
    llvm::SmallVector<QualType, 8> Params;
7603
98
    Params.append(PTy->param_type_begin(), PTy->param_type_end());
7604
98
    Params.insert(Params.end(), NumAppendArgs, InteropType);
7605
98
    AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7606
98
                                             PTy->getExtProtoInfo());
7607
98
  }
7608
7609
  // Convert VariantRef expression to the type of the original function to
7610
  // resolve possible conflicts.
7611
2.18k
  ExprResult VariantRefCast = VariantRef;
7612
2.18k
  if (LangOpts.CPlusPlus) {
7613
1.77k
    QualType FnPtrType;
7614
1.77k
    auto *Method = dyn_cast<CXXMethodDecl>(FD);
7615
1.77k
    if (Method && 
!Method->isStatic()384
) {
7616
370
      const Type *ClassType =
7617
370
          Context.getTypeDeclType(Method->getParent()).getTypePtr();
7618
370
      FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7619
370
      ExprResult ER;
7620
370
      {
7621
        // Build adrr_of unary op to correctly handle type checks for member
7622
        // functions.
7623
370
        Sema::TentativeAnalysisScope Trap(*this);
7624
370
        ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7625
370
                                  VariantRef);
7626
370
      }
7627
370
      if (!ER.isUsable()) {
7628
0
        Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7629
0
            << VariantId << VariantRef->getSourceRange();
7630
0
        return std::nullopt;
7631
0
      }
7632
370
      VariantRef = ER.get();
7633
1.40k
    } else {
7634
1.40k
      FnPtrType = Context.getPointerType(AdjustedFnType);
7635
1.40k
    }
7636
1.77k
    QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7637
1.77k
    if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7638
652
      ImplicitConversionSequence ICS = TryImplicitConversion(
7639
652
          VariantRef, FnPtrType.getUnqualifiedType(),
7640
652
          /*SuppressUserConversions=*/false, AllowedExplicit::None,
7641
652
          /*InOverloadResolution=*/false,
7642
652
          /*CStyle=*/false,
7643
652
          /*AllowObjCWritebackConversion=*/false);
7644
652
      if (ICS.isFailure()) {
7645
42
        Diag(VariantRef->getExprLoc(),
7646
42
             diag::err_omp_declare_variant_incompat_types)
7647
42
            << VariantRef->getType()
7648
42
            << ((Method && 
!Method->isStatic()16
) ?
FnPtrType12
:
FD->getType()30
)
7649
42
            << (NumAppendArgs ? 
124
:
018
) << VariantRef->getSourceRange();
7650
42
        return std::nullopt;
7651
42
      }
7652
610
      VariantRefCast = PerformImplicitConversion(
7653
610
          VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7654
610
      if (!VariantRefCast.isUsable())
7655
0
        return std::nullopt;
7656
610
    }
7657
    // Drop previously built artificial addr_of unary op for member functions.
7658
1.72k
    if (Method && 
!Method->isStatic()368
) {
7659
358
      Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7660
358
      if (auto *UO = dyn_cast<UnaryOperator>(
7661
358
              PossibleAddrOfVariantRef->IgnoreImplicit()))
7662
358
        VariantRefCast = UO->getSubExpr();
7663
358
    }
7664
1.72k
  }
7665
7666
2.14k
  ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7667
2.14k
  if (!ER.isUsable() ||
7668
2.14k
      !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7669
0
    Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7670
0
        << VariantId << VariantRef->getSourceRange();
7671
0
    return std::nullopt;
7672
0
  }
7673
7674
  // The VariantRef must point to function.
7675
2.14k
  auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7676
2.14k
  if (!DRE) {
7677
0
    Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7678
0
        << VariantId << VariantRef->getSourceRange();
7679
0
    return std::nullopt;
7680
0
  }
7681
2.14k
  auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7682
2.14k
  if (!NewFD) {
7683
0
    Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7684
0
        << VariantId << VariantRef->getSourceRange();
7685
0
    return std::nullopt;
7686
0
  }
7687
7688
2.14k
  if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7689
4
    Diag(VariantRef->getExprLoc(),
7690
4
         diag::err_omp_declare_variant_same_base_function)
7691
4
        << VariantRef->getSourceRange();
7692
4
    return std::nullopt;
7693
4
  }
7694
7695
  // Check if function types are compatible in C.
7696
2.14k
  if (!LangOpts.CPlusPlus) {
7697
412
    QualType NewType =
7698
412
        Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7699
412
    if (NewType.isNull()) {
7700
18
      Diag(VariantRef->getExprLoc(),
7701
18
           diag::err_omp_declare_variant_incompat_types)
7702
18
          << NewFD->getType() << FD->getType() << (NumAppendArgs ? 
18
:
010
)
7703
18
          << VariantRef->getSourceRange();
7704
18
      return std::nullopt;
7705
18
    }
7706
394
    if (NewType->isFunctionProtoType()) {
7707
390
      if (FD->getType()->isFunctionNoProtoType())
7708
14
        setPrototype(*this, FD, NewFD, NewType);
7709
376
      else if (NewFD->getType()->isFunctionNoProtoType())
7710
4
        setPrototype(*this, NewFD, FD, NewType);
7711
390
    }
7712
394
  }
7713
7714
  // Check if variant function is not marked with declare variant directive.
7715
2.12k
  if (NewFD->hasAttrs() && 
NewFD->hasAttr<OMPDeclareVariantAttr>()896
) {
7716
4
    Diag(VariantRef->getExprLoc(),
7717
4
         diag::warn_omp_declare_variant_marked_as_declare_variant)
7718
4
        << VariantRef->getSourceRange();
7719
4
    SourceRange SR =
7720
4
        NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7721
4
    Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7722
4
    return std::nullopt;
7723
4
  }
7724
7725
2.11k
  enum DoesntSupport {
7726
2.11k
    VirtFuncs = 1,
7727
2.11k
    Constructors = 3,
7728
2.11k
    Destructors = 4,
7729
2.11k
    DeletedFuncs = 5,
7730
2.11k
    DefaultedFuncs = 6,
7731
2.11k
    ConstexprFuncs = 7,
7732
2.11k
    ConstevalFuncs = 8,
7733
2.11k
  };
7734
2.11k
  if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7735
368
    if (CXXFD->isVirtual()) {
7736
4
      Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7737
4
          << VirtFuncs;
7738
4
      return std::nullopt;
7739
4
    }
7740
7741
364
    if (isa<CXXConstructorDecl>(FD)) {
7742
4
      Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7743
4
          << Constructors;
7744
4
      return std::nullopt;
7745
4
    }
7746
7747
360
    if (isa<CXXDestructorDecl>(FD)) {
7748
4
      Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7749
4
          << Destructors;
7750
4
      return std::nullopt;
7751
4
    }
7752
360
  }
7753
7754
2.10k
  if (FD->isDeleted()) {
7755
4
    Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7756
4
        << DeletedFuncs;
7757
4
    return std::nullopt;
7758
4
  }
7759
7760
2.10k
  if (FD->isDefaulted()) {
7761
4
    Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7762
4
        << DefaultedFuncs;
7763
4
    return std::nullopt;
7764
4
  }
7765
7766
2.09k
  if (FD->isConstexpr()) {
7767
4
    Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7768
4
        << (NewFD->isConsteval() ? 
ConstevalFuncs0
: ConstexprFuncs);
7769
4
    return std::nullopt;
7770
4
  }
7771
7772
  // Check general compatibility.
7773
2.09k
  if (areMultiversionVariantFunctionsCompatible(
7774
2.09k
          FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7775
2.09k
          PartialDiagnosticAt(SourceLocation(),
7776
2.09k
                              PartialDiagnostic::NullDiagnostic()),
7777
2.09k
          PartialDiagnosticAt(
7778
2.09k
              VariantRef->getExprLoc(),
7779
2.09k
              PDiag(diag::err_omp_declare_variant_doesnt_support)),
7780
2.09k
          PartialDiagnosticAt(VariantRef->getExprLoc(),
7781
2.09k
                              PDiag(diag::err_omp_declare_variant_diff)
7782
2.09k
                                  << FD->getLocation()),
7783
2.09k
          /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7784
2.09k
          /*CLinkageMayDiffer=*/true))
7785
36
    return std::nullopt;
7786
2.05k
  return std::make_pair(FD, cast<Expr>(DRE));
7787
2.09k
}
7788
7789
void Sema::ActOnOpenMPDeclareVariantDirective(
7790
    FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7791
    ArrayRef<Expr *> AdjustArgsNothing,
7792
    ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7793
    ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
7794
1.90k
    SourceLocation AppendArgsLoc, SourceRange SR) {
7795
7796
  // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7797
  // An adjust_args clause or append_args clause can only be specified if the
7798
  // dispatch selector of the construct selector set appears in the match
7799
  // clause.
7800
7801
1.90k
  SmallVector<Expr *, 8> AllAdjustArgs;
7802
1.90k
  llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7803
1.90k
  llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7804
7805
1.90k
  if (!AllAdjustArgs.empty() || 
!AppendArgs.empty()1.85k
) {
7806
107
    VariantMatchInfo VMI;
7807
107
    TI.getAsVariantMatchInfo(Context, VMI);
7808
107
    if (!llvm::is_contained(
7809
107
            VMI.ConstructTraits,
7810
107
            llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7811
16
      if (!AllAdjustArgs.empty())
7812
8
        Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7813
8
            << getOpenMPClauseName(OMPC_adjust_args);
7814
16
      if (!AppendArgs.empty())
7815
8
        Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7816
8
            << getOpenMPClauseName(OMPC_append_args);
7817
16
      return;
7818
16
    }
7819
107
  }
7820
7821
  // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7822
  // Each argument can only appear in a single adjust_args clause for each
7823
  // declare variant directive.
7824
1.88k
  llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7825
7826
1.88k
  for (Expr *E : AllAdjustArgs) {
7827
69
    E = E->IgnoreParenImpCasts();
7828
69
    if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7829
69
      if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7830
65
        const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7831
65
        if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7832
65
            FD->getParamDecl(PVD->getFunctionScopeIndex())
7833
65
                    ->getCanonicalDecl() == CanonPVD) {
7834
          // It's a parameter of the function, check duplicates.
7835
65
          if (!AdjustVars.insert(CanonPVD).second) {
7836
8
            Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7837
8
                << PVD;
7838
8
            return;
7839
8
          }
7840
57
          continue;
7841
65
        }
7842
65
      }
7843
69
    }
7844
    // Anything that is not a function parameter is an error.
7845
4
    Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7846
4
    return;
7847
69
  }
7848
7849
1.87k
  auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7850
1.87k
      Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7851
1.87k
      AdjustArgsNothing.size(),
7852
1.87k
      const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7853
1.87k
      AdjustArgsNeedDevicePtr.size(),
7854
1.87k
      const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR);
7855
1.87k
  FD->addAttr(NewAttr);
7856
1.87k
}
7857
7858
StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7859
                                              Stmt *AStmt,
7860
                                              SourceLocation StartLoc,
7861
43.7k
                                              SourceLocation EndLoc) {
7862
43.7k
  if (!AStmt)
7863
2.78k
    return StmtError();
7864
7865
40.9k
  auto *CS = cast<CapturedStmt>(AStmt);
7866
  // 1.2.2 OpenMP Language Terminology
7867
  // Structured block - An executable statement with a single entry at the
7868
  // top and a single exit at the bottom.
7869
  // The point of exit cannot be a branch out of the structured block.
7870
  // longjmp() and throw() must not violate the entry/exit criteria.
7871
40.9k
  CS->getCapturedDecl()->setNothrow();
7872
7873
40.9k
  setFunctionHasBranchProtectedScope();
7874
7875
40.9k
  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7876
40.9k
                                      DSAStack->getTaskgroupReductionRef(),
7877
40.9k
                                      DSAStack->isCancelRegion());
7878
43.7k
}
7879
7880
namespace {
7881
/// Iteration space of a single for loop.
7882
struct LoopIterationSpace final {
7883
  /// True if the condition operator is the strict compare operator (<, > or
7884
  /// !=).
7885
  bool IsStrictCompare = false;
7886
  /// Condition of the loop.
7887
  Expr *PreCond = nullptr;
7888
  /// This expression calculates the number of iterations in the loop.
7889
  /// It is always possible to calculate it before starting the loop.
7890
  Expr *NumIterations = nullptr;
7891
  /// The loop counter variable.
7892
  Expr *CounterVar = nullptr;
7893
  /// Private loop counter variable.
7894
  Expr *PrivateCounterVar = nullptr;
7895
  /// This is initializer for the initial value of #CounterVar.
7896
  Expr *CounterInit = nullptr;
7897
  /// This is step for the #CounterVar used to generate its update:
7898
  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7899
  Expr *CounterStep = nullptr;
7900
  /// Should step be subtracted?
7901
  bool Subtract = false;
7902
  /// Source range of the loop init.
7903
  SourceRange InitSrcRange;
7904
  /// Source range of the loop condition.
7905
  SourceRange CondSrcRange;
7906
  /// Source range of the loop increment.
7907
  SourceRange IncSrcRange;
7908
  /// Minimum value that can have the loop control variable. Used to support
7909
  /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7910
  /// since only such variables can be used in non-loop invariant expressions.
7911
  Expr *MinValue = nullptr;
7912
  /// Maximum value that can have the loop control variable. Used to support
7913
  /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7914
  /// since only such variables can be used in non-loop invariant expressions.
7915
  Expr *MaxValue = nullptr;
7916
  /// true, if the lower bound depends on the outer loop control var.
7917
  bool IsNonRectangularLB = false;
7918
  /// true, if the upper bound depends on the outer loop control var.
7919
  bool IsNonRectangularUB = false;
7920
  /// Index of the loop this loop depends on and forms non-rectangular loop
7921
  /// nest.
7922
  unsigned LoopDependentIdx = 0;
7923
  /// Final condition for the non-rectangular loop nest support. It is used to
7924
  /// check that the number of iterations for this particular counter must be
7925
  /// finished.
7926
  Expr *FinalCondition = nullptr;
7927
};
7928
7929
/// Helper class for checking canonical form of the OpenMP loops and
7930
/// extracting iteration space of each loop in the loop nest, that will be used
7931
/// for IR generation.
7932
class OpenMPIterationSpaceChecker {
7933
  /// Reference to Sema.
7934
  Sema &SemaRef;
7935
  /// Does the loop associated directive support non-rectangular loops?
7936
  bool SupportsNonRectangular;
7937
  /// Data-sharing stack.
7938
  DSAStackTy &Stack;
7939
  /// A location for diagnostics (when there is no some better location).
7940
  SourceLocation DefaultLoc;
7941
  /// A location for diagnostics (when increment is not compatible).
7942
  SourceLocation ConditionLoc;
7943
  /// A source location for referring to loop init later.
7944
  SourceRange InitSrcRange;
7945
  /// A source location for referring to condition later.
7946
  SourceRange ConditionSrcRange;
7947
  /// A source location for referring to increment later.
7948
  SourceRange IncrementSrcRange;
7949
  /// Loop variable.
7950
  ValueDecl *LCDecl = nullptr;
7951
  /// Reference to loop variable.
7952
  Expr *LCRef = nullptr;
7953
  /// Lower bound (initializer for the var).
7954
  Expr *LB = nullptr;
7955
  /// Upper bound.
7956
  Expr *UB = nullptr;
7957
  /// Loop step (increment).
7958
  Expr *Step = nullptr;
7959
  /// This flag is true when condition is one of:
7960
  ///   Var <  UB
7961
  ///   Var <= UB
7962
  ///   UB  >  Var
7963
  ///   UB  >= Var
7964
  /// This will have no value when the condition is !=
7965
  std::optional<bool> TestIsLessOp;
7966
  /// This flag is true when condition is strict ( < or > ).
7967
  bool TestIsStrictOp = false;
7968
  /// This flag is true when step is subtracted on each iteration.
7969
  bool SubtractStep = false;
7970
  /// The outer loop counter this loop depends on (if any).
7971
  const ValueDecl *DepDecl = nullptr;
7972
  /// Contains number of loop (starts from 1) on which loop counter init
7973
  /// expression of this loop depends on.
7974
  std::optional<unsigned> InitDependOnLC;
7975
  /// Contains number of loop (starts from 1) on which loop counter condition
7976
  /// expression of this loop depends on.
7977
  std::optional<unsigned> CondDependOnLC;
7978
  /// Checks if the provide statement depends on the loop counter.
7979
  std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S,
7980
                                                  bool IsInitializer);
7981
  /// Original condition required for checking of the exit condition for
7982
  /// non-rectangular loop.
7983
  Expr *Condition = nullptr;
7984
7985
public:
7986
  OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7987
                              DSAStackTy &Stack, SourceLocation DefaultLoc)
7988
492k
      : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7989
492k
        Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7990
  /// Check init-expr for canonical loop form and save loop counter
7991
  /// variable - #Var and its initialization value - #LB.
7992
  bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7993
  /// Check test-expr for canonical form, save upper-bound (#UB), flags
7994
  /// for less/greater and for strict/non-strict comparison.
7995
  bool checkAndSetCond(Expr *S);
7996
  /// Check incr-expr for canonical loop form and return true if it
7997
  /// does not conform, otherwise save loop step (#Step).
7998
  bool checkAndSetInc(Expr *S);
7999
  /// Return the loop counter variable.
8000
490k
  ValueDecl *getLoopDecl() const { return LCDecl; }
8001
  /// Return the reference expression to loop counter variable.
8002
261k
  Expr *getLoopDeclRefExpr() const { return LCRef; }
8003
  /// Source range of the loop init.
8004
165k
  SourceRange getInitSrcRange() const { return InitSrcRange; }
8005
  /// Source range of the loop condition.
8006
165k
  SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
8007
  /// Source range of the loop increment.
8008
165k
  SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
8009
  /// True if the step should be subtracted.
8010
165k
  bool shouldSubtractStep() const { return SubtractStep; }
8011
  /// True, if the compare operator is strict (<, > or !=).
8012
165k
  bool isStrictTestOp() const { return TestIsStrictOp; }
8013
  /// Build the expression to calculate the number of iterations.
8014
  Expr *buildNumIterations(
8015
      Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8016
      llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8017
  /// Build the precondition expression for the loops.
8018
  Expr *
8019
  buildPreCond(Scope *S, Expr *Cond,
8020
               llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8021
  /// Build reference expression to the counter be used for codegen.
8022
  DeclRefExpr *
8023
  buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8024
                  DSAStackTy &DSA) const;
8025
  /// Build reference expression to the private counter be used for
8026
  /// codegen.
8027
  Expr *buildPrivateCounterVar() const;
8028
  /// Build initialization of the counter be used for codegen.
8029
  Expr *buildCounterInit() const;
8030
  /// Build step of the counter be used for codegen.
8031
  Expr *buildCounterStep() const;
8032
  /// Build loop data with counter value for depend clauses in ordered
8033
  /// directives.
8034
  Expr *
8035
  buildOrderedLoopData(Scope *S, Expr *Counter,
8036
                       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8037
                       SourceLocation Loc, Expr *Inc = nullptr,
8038
                       OverloadedOperatorKind OOK = OO_Amp);
8039
  /// Builds the minimum value for the loop counter.
8040
  std::pair<Expr *, Expr *> buildMinMaxValues(
8041
      Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8042
  /// Builds final condition for the non-rectangular loops.
8043
  Expr *buildFinalCondition(Scope *S) const;
8044
  /// Return true if any expression is dependent.
8045
  bool dependent() const;
8046
  /// Returns true if the initializer forms non-rectangular loop.
8047
165k
  bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); }
8048
  /// Returns true if the condition forms non-rectangular loop.
8049
165k
  bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); }
8050
  /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
8051
165k
  unsigned getLoopDependentIdx() const {
8052
165k
    return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
8053
165k
  }
8054
8055
private:
8056
  /// Check the right-hand side of an assignment in the increment
8057
  /// expression.
8058
  bool checkAndSetIncRHS(Expr *RHS);
8059
  /// Helper to set loop counter variable and its initializer.
8060
  bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
8061
                      bool EmitDiags);
8062
  /// Helper to set upper bound.
8063
  bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp,
8064
             SourceRange SR, SourceLocation SL);
8065
  /// Helper to set loop increment.
8066
  bool setStep(Expr *NewStep, bool Subtract);
8067
};
8068
8069
233k
bool OpenMPIterationSpaceChecker::dependent() const {
8070
233k
  if (!LCDecl) {
8071
1.69k
    assert(!LB && !UB && !Step);
8072
1.69k
    return false;
8073
1.69k
  }
8074
231k
  return LCDecl->getType()->isDependentType() ||
8075
231k
         
(225k
LB225k
&&
LB->isValueDependent()225k
) ||
(221k
UB221k
&&
UB->isValueDependent()220k
) ||
8076
231k
         
(216k
Step216k
&&
Step->isValueDependent()211k
);
8077
233k
}
8078
8079
bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
8080
                                                 Expr *NewLCRefExpr,
8081
490k
                                                 Expr *NewLB, bool EmitDiags) {
8082
  // State consistency checking to ensure correct usage.
8083
490k
  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
8084
490k
         UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
8085
490k
  if (!NewLCDecl || !NewLB || NewLB->containsErrors())
8086
0
    return true;
8087
490k
  LCDecl = getCanonicalDecl(NewLCDecl);
8088
490k
  LCRef = NewLCRefExpr;
8089
490k
  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
8090
6.85k
    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8091
6.85k
      if ((Ctor->isCopyOrMoveConstructor() ||
8092
6.85k
           
Ctor->isConvertingConstructor(/*AllowExplicit=*/false)1.25k
) &&
8093
6.85k
          
CE->getNumArgs() > 05.88k
&&
CE->getArg(0) != nullptr5.88k
)
8094
5.88k
        NewLB = CE->getArg(0)->IgnoreParenImpCasts();
8095
490k
  LB = NewLB;
8096
490k
  if (EmitDiags)
8097
229k
    InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
8098
490k
  return false;
8099
490k
}
8100
8101
bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp,
8102
                                        bool StrictOp, SourceRange SR,
8103
229k
                                        SourceLocation SL) {
8104
  // State consistency checking to ensure correct usage.
8105
229k
  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
8106
229k
         Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
8107
229k
  if (!NewUB || NewUB->containsErrors())
8108
4
    return true;
8109
229k
  UB = NewUB;
8110
229k
  if (LessOp)
8111
228k
    TestIsLessOp = LessOp;
8112
229k
  TestIsStrictOp = StrictOp;
8113
229k
  ConditionSrcRange = SR;
8114
229k
  ConditionLoc = SL;
8115
229k
  CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
8116
229k
  return false;
8117
229k
}
8118
8119
228k
bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
8120
  // State consistency checking to ensure correct usage.
8121
228k
  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
8122
228k
  if (!NewStep || NewStep->containsErrors())
8123
0
    return true;
8124
228k
  if (!NewStep->isValueDependent()) {
8125
    // Check that the step is integer expression.
8126
227k
    SourceLocation StepLoc = NewStep->getBeginLoc();
8127
227k
    ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
8128
227k
        StepLoc, getExprAsWritten(NewStep));
8129
227k
    if (Val.isInvalid())
8130
0
      return true;
8131
227k
    NewStep = Val.get();
8132
8133
    // OpenMP [2.6, Canonical Loop Form, Restrictions]
8134
    //  If test-expr is of form var relational-op b and relational-op is < or
8135
    //  <= then incr-expr must cause var to increase on each iteration of the
8136
    //  loop. If test-expr is of form var relational-op b and relational-op is
8137
    //  > or >= then incr-expr must cause var to decrease on each iteration of
8138
    //  the loop.
8139
    //  If test-expr is of form b relational-op var and relational-op is < or
8140
    //  <= then incr-expr must cause var to decrease on each iteration of the
8141
    //  loop. If test-expr is of form b relational-op var and relational-op is
8142
    //  > or >= then incr-expr must cause var to increase on each iteration of
8143
    //  the loop.
8144
227k
    std::optional<llvm::APSInt> Result =
8145
227k
        NewStep->getIntegerConstantExpr(SemaRef.Context);
8146
227k
    bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
8147
227k
    bool IsConstNeg =
8148
227k
        Result && 
Result->isSigned()227k
&&
(Subtract != Result->isNegative())227k
;
8149
227k
    bool IsConstPos =
8150
227k
        Result && 
Result->isSigned()227k
&&
(Subtract == Result->isNegative())227k
;
8151
227k
    bool IsConstZero = Result && 
!Result->getBoolValue()227k
;
8152
8153
    // != with increment is treated as <; != with decrement is treated as >
8154
227k
    if (!TestIsLessOp)
8155
990
      TestIsLessOp = IsConstPos || 
(16
IsUnsigned16
&&
!Subtract0
);
8156
227k
    if (UB && 
(227k
IsConstZero227k
||
8157
227k
               
(226k
*TestIsLessOp226k
?
(224k
IsConstNeg224k
||
(223k
IsUnsigned223k
&&
Subtract387
))
8158
226k
                              : 
(1.84k
IsConstPos1.84k
||
(1.12k
IsUnsigned1.12k
&&
!Subtract0
))))) {
8159
2.28k
      SemaRef.Diag(NewStep->getExprLoc(),
8160
2.28k
                   diag::err_omp_loop_incr_not_compatible)
8161
2.28k
          << LCDecl << *TestIsLessOp << NewStep->getSourceRange();
8162
2.28k
      SemaRef.Diag(ConditionLoc,
8163
2.28k
                   diag::note_omp_loop_cond_requres_compatible_incr)
8164
2.28k
          << *TestIsLessOp << ConditionSrcRange;
8165
2.28k
      return true;
8166
2.28k
    }
8167
225k
    if (*TestIsLessOp == Subtract) {
8168
885
      NewStep =
8169
885
          SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
8170
885
              .get();
8171
885
      Subtract = !Subtract;
8172
885
    }
8173
225k
  }
8174
8175
226k
  Step = NewStep;
8176
226k
  SubtractStep = Subtract;
8177
226k
  return false;
8178
228k
}
8179
8180
namespace {
8181
/// Checker for the non-rectangular loops. Checks if the initializer or
8182
/// condition expression references loop counter variable.
8183
class LoopCounterRefChecker final
8184
    : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
8185
  Sema &SemaRef;
8186
  DSAStackTy &Stack;
8187
  const ValueDecl *CurLCDecl = nullptr;
8188
  const ValueDecl *DepDecl = nullptr;
8189
  const ValueDecl *PrevDepDecl = nullptr;
8190
  bool IsInitializer = true;
8191
  bool SupportsNonRectangular;
8192
  unsigned BaseLoopId = 0;
8193
52.1k
  bool checkDecl(const Expr *E, const ValueDecl *VD) {
8194
52.1k
    if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
8195
49
      SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8196
49
          << (IsInitializer ? 
016
:
133
);
8197
49
      return false;
8198
49
    }
8199
52.1k
    const auto &&Data = Stack.isLoopControlVariable(VD);
8200
    // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
8201
    // The type of the loop iterator on which we depend may not have a random
8202
    // access iterator type.
8203
52.1k
    if (Data.first && 
VD->getType()->isRecordType()219
) {
8204
8
      SmallString<128> Name;
8205
8
      llvm::raw_svector_ostream OS(Name);
8206
8
      VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8207
8
                               /*Qualified=*/true);
8208
8
      SemaRef.Diag(E->getExprLoc(),
8209
8
                   diag::err_omp_wrong_dependency_iterator_type)
8210
8
          << OS.str();
8211
8
      SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
8212
8
      return false;
8213
8
    }
8214
52.1k
    if (Data.first && 
!SupportsNonRectangular211
) {
8215
3
      SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
8216
3
      return false;
8217
3
    }
8218
52.1k
    if (Data.first &&
8219
52.1k
        
(208
DepDecl208
||
(180
PrevDepDecl180
&&
8220
180
                     
getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)77
))) {
8221
44
      if (!DepDecl && 
PrevDepDecl16
)
8222
16
        DepDecl = PrevDepDecl;
8223
44
      SmallString<128> Name;
8224
44
      llvm::raw_svector_ostream OS(Name);
8225
44
      DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8226
44
                                    /*Qualified=*/true);
8227
44
      SemaRef.Diag(E->getExprLoc(),
8228
44
                   diag::err_omp_invariant_or_linear_dependency)
8229
44
          << OS.str();
8230
44
      return false;
8231
44
    }
8232
52.0k
    if (Data.first) {
8233
164
      DepDecl = VD;
8234
164
      BaseLoopId = Data.first;
8235
164
    }
8236
52.0k
    return Data.first;
8237
52.1k
  }
8238
8239
public:
8240
61.0k
  bool VisitDeclRefExpr(const DeclRefExpr *E) {
8241
61.0k
    const ValueDecl *VD = E->getDecl();
8242
61.0k
    if (isa<VarDecl>(VD))
8243
51.6k
      return checkDecl(E, VD);
8244
9.40k
    return false;
8245
61.0k
  }
8246
1.53k
  bool VisitMemberExpr(const MemberExpr *E) {
8247
1.53k
    if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
8248
536
      const ValueDecl *VD = E->getMemberDecl();
8249
536
      if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8250
516
        return checkDecl(E, VD);
8251
536
    }
8252
1.01k
    return false;
8253
1.53k
  }
8254
466k
  bool VisitStmt(const Stmt *S) {
8255
466k
    bool Res = false;
8256
466k
    for (const Stmt *Child : S->children())
8257
70.2k
      Res = (Child && Visit(Child)) || 
Res69.8k
;
8258
466k
    return Res;
8259
466k
  }
8260
  explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
8261
                                 const ValueDecl *CurLCDecl, bool IsInitializer,
8262
                                 const ValueDecl *PrevDepDecl = nullptr,
8263
                                 bool SupportsNonRectangular = true)
8264
458k
      : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8265
458k
        PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8266
458k
        SupportsNonRectangular(SupportsNonRectangular) {}
8267
164
  unsigned getBaseLoopId() const {
8268
164
    assert(CurLCDecl && "Expected loop dependency.");
8269
164
    return BaseLoopId;
8270
164
  }
8271
164
  const ValueDecl *getDepDecl() const {
8272
164
    assert(CurLCDecl && "Expected loop dependency.");
8273
164
    return DepDecl;
8274
164
  }
8275
};
8276
} // namespace
8277
8278
std::optional<unsigned>
8279
OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
8280
458k
                                                     bool IsInitializer) {
8281
  // Check for the non-rectangular loops.
8282
458k
  LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8283
458k
                                        DepDecl, SupportsNonRectangular);
8284
458k
  if (LoopStmtChecker.Visit(S)) {
8285
164
    DepDecl = LoopStmtChecker.getDepDecl();
8286
164
    return LoopStmtChecker.getBaseLoopId();
8287
164
  }
8288
458k
  return std::nullopt;
8289
458k
}
8290
8291
492k
bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
8292
  // Check init-expr for canonical loop form and save loop counter
8293
  // variable - #Var and its initialization value - #LB.
8294
  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8295
  //   var = lb
8296
  //   integer-type var = lb
8297
  //   random-access-iterator-type var = lb
8298
  //   pointer-type var = lb
8299
  //
8300
492k
  if (!S) {
8301
120
    if (EmitDiags) {
8302
120
      SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8303
120
    }
8304
120
    return true;
8305
120
  }
8306
492k
  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8307
260
    if (!ExprTemp->cleanupsHaveSideEffects())
8308
260
      S = ExprTemp->getSubExpr();
8309
8310
492k
  InitSrcRange = S->getSourceRange();
8311
492k
  if (Expr *E = dyn_cast<Expr>(S))
8312
75.5k
    S = E->IgnoreParens();
8313
492k
  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8314
74.5k
    if (BO->getOpcode() == BO_Assign) {
8315
74.3k
      Expr *LHS = BO->getLHS()->IgnoreParens();
8316
74.3k
      if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8317
73.7k
        if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8318
40
          if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8319
40
            return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8320
40
                                  EmitDiags);
8321
73.6k
        return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8322
73.7k
      }
8323
628
      if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8324
380
        if (ME->isArrow() &&
8325
380
            isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8326
380
          return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8327
380
                                EmitDiags);
8328
380
      }
8329
628
    }
8330
418k
  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
8331
417k
    if (DS->isSingleDecl()) {
8332
416k
      if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8333
416k
        if (Var->hasInit() && 
!Var->getType()->isReferenceType()416k
) {
8334
          // Accept non-canonical init form here but emit ext. warning.
8335
416k
          if (Var->getInitStyle() != VarDecl::CInit && 
EmitDiags1.68k
)
8336
840
            SemaRef.Diag(S->getBeginLoc(),
8337
840
                         diag::ext_omp_loop_not_canonical_init)
8338
840
                << S->getSourceRange();
8339
416k
          return setLCDeclAndLB(
8340
416k
              Var,
8341
416k
              buildDeclRefExpr(SemaRef, Var,
8342
416k
                               Var->getType().getNonReferenceType(),
8343
416k
                               DS->getBeginLoc()),
8344
416k
              Var->getInit(), EmitDiags);
8345
416k
        }
8346
416k
      }
8347
416k
    }
8348
417k
  } else 
if (auto *960
CE960
= dyn_cast<CXXOperatorCallExpr>(S)) {
8349
960
    if (CE->getOperator() == OO_Equal) {
8350
720
      Expr *LHS = CE->getArg(0);
8351
720
      if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8352
720
        if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8353
0
          if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8354
0
            return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8355
0
                                  EmitDiags);
8356
720
        return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8357
720
      }
8358
0
      if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8359
0
        if (ME->isArrow() &&
8360
0
            isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8361
0
          return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8362
0
                                EmitDiags);
8363
0
      }
8364
0
    }
8365
960
  }
8366
8367
1.68k
  if (dependent() || SemaRef.CurContext->isDependentContext())
8368
8
    return false;
8369
1.68k
  if (EmitDiags) {
8370
840
    SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8371
840
        << S->getSourceRange();
8372
840
  }
8373
1.68k
  return true;
8374
1.68k
}
8375
8376
/// Ignore parenthesizes, implicit casts, copy constructor and return the
8377
/// variable (which may be the loop variable) if possible.
8378
461k
static const ValueDecl *getInitLCDecl(const Expr *E) {
8379
461k
  if (!E)
8380
0
    return nullptr;
8381
461k
  E = getExprAsWritten(E);
8382
461k
  if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8383
862
    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8384
862
      if ((Ctor->isCopyOrMoveConstructor() ||
8385
862
           
Ctor->isConvertingConstructor(/*AllowExplicit=*/false)22
) &&
8386
862
          CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8387
862
        E = CE->getArg(0)->IgnoreParenImpCasts();
8388
461k
  if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8389
460k
    if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8390
460k
      return getCanonicalDecl(VD);
8391
460k
  }
8392
724
  if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8393
236
    if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8394
236
      return getCanonicalDecl(ME->getMemberDecl());
8395
488
  return nullptr;
8396
724
}
8397
8398
229k
bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
8399
  // Check test-expr for canonical form, save upper-bound UB, flags for
8400
  // less/greater and for strict/non-strict comparison.
8401
  // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8402
  //   var relational-op b
8403
  //   b relational-op var
8404
  //
8405
229k
  bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8406
229k
  if (!S) {
8407
120
    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8408
120
        << (IneqCondIsCanonical ? 
162
:
058
) << LCDecl;
8409
120
    return true;
8410
120
  }
8411
229k
  Condition = S;
8412
229k
  S = getExprAsWritten(S);
8413
229k
  SourceLocation CondLoc = S->getBeginLoc();
8414
229k
  auto &&CheckAndSetCond =
8415
229k
      [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS,
8416
229k
                                  const Expr *RHS, SourceRange SR,
8417
229k
                                  SourceLocation OpLoc) -> std::optional<bool> {
8418
229k
    if (BinaryOperator::isRelationalOp(Opcode)) {
8419
229k
      if (getInitLCDecl(LHS) == LCDecl)
8420
228k
        return setUB(const_cast<Expr *>(RHS),
8421
228k
                     (Opcode == BO_LT || 
Opcode == BO_LE3.55k
),
8422
228k
                     (Opcode == BO_LT || 
Opcode == BO_GT3.55k
), SR, OpLoc);
8423
242
      if (getInitLCDecl(RHS) == LCDecl)
8424
0
        return setUB(const_cast<Expr *>(LHS),
8425
0
                     (Opcode == BO_GT || Opcode == BO_GE),
8426
0
                     (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8427
388
    } else if (IneqCondIsCanonical && 
Opcode == BO_NE272
) {
8428
210
      return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : 
LHS0
),
8429
210
                   /*LessOp=*/std::nullopt,
8430
210
                   /*StrictOp=*/true, SR, OpLoc);
8431
210
    }
8432
420
    return std::nullopt;
8433
229k
  };
8434
229k
  std::optional<bool> Res;
8435
229k
  if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8436
4
    CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
8437
4
    Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
8438
4
                          RBO->getOperatorLoc());
8439
229k
  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8440
225k
    Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8441
225k
                          BO->getSourceRange(), BO->getOperatorLoc());
8442
225k
  } else 
if (auto *4.02k
CE4.02k
= dyn_cast<CXXOperatorCallExpr>(S)) {
8443
3.78k
    if (CE->getNumArgs() == 2) {
8444
3.66k
      Res = CheckAndSetCond(
8445
3.66k
          BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
8446
3.66k
          CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8447
3.66k
    }
8448
3.78k
  }
8449
229k
  if (Res)
8450
229k
    return *Res;
8451
776
  if (dependent() || SemaRef.CurContext->isDependentContext())
8452
0
    return false;
8453
776
  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8454
776
      << (IneqCondIsCanonical ? 
1372
:
0404
) << S->getSourceRange() << LCDecl;
8455
776
  return true;
8456
776
}
8457
8458
2.16k
bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8459
  // RHS of canonical loop form increment can be:
8460
  //   var + incr
8461
  //   incr + var
8462
  //   var - incr
8463
  //
8464
2.16k
  RHS = RHS->IgnoreParenImpCasts();
8465
2.16k
  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8466
960
    if (BO->isAdditiveOp()) {
8467
840
      bool IsAdd = BO->getOpcode() == BO_Add;
8468
840
      if (getInitLCDecl(BO->getLHS()) == LCDecl)
8469
720
        return setStep(BO->getRHS(), !IsAdd);
8470
120
      if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8471
120
        return setStep(BO->getLHS(), /*Subtract=*/false);
8472
120
    }
8473
1.20k
  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8474
1.20k
    bool IsAdd = CE->getOperator() == OO_Plus;
8475
1.20k
    if ((IsAdd || 
CE->getOperator() == OO_Minus360
) && CE->getNumArgs() == 2) {
8476
1.08k
      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8477
840
        return setStep(CE->getArg(1), !IsAdd);
8478
240
      if (IsAdd && 
getInitLCDecl(CE->getArg(1)) == LCDecl120
)
8479
120
        return setStep(CE->getArg(0), /*Subtract=*/false);
8480
240
    }
8481
1.20k
  }
8482
360
  if (dependent() || SemaRef.CurContext->isDependentContext())
8483
0
    return false;
8484
360
  SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8485
360
      << RHS->getSourceRange() << LCDecl;
8486
360
  return true;
8487
360
}
8488
8489
229k
bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8490
  // Check incr-expr for canonical loop form and return true if it
8491
  // does not conform.
8492
  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8493
  //   ++var
8494
  //   var++
8495
  //   --var
8496
  //   var--
8497
  //   var += incr
8498
  //   var -= incr
8499
  //   var = var + incr
8500
  //   var = incr + var
8501
  //   var = var - incr
8502
  //
8503
229k
  if (!S) {
8504
120
    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8505
120
    return true;
8506
120
  }
8507
229k
  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8508
960
    if (!ExprTemp->cleanupsHaveSideEffects())
8509
960
      S = ExprTemp->getSubExpr();
8510
8511
229k
  IncrementSrcRange = S->getSourceRange();
8512
229k
  S = S->IgnoreParens();
8513
229k
  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8514
220k
    if (UO->isIncrementDecrementOp() &&
8515
220k
        
getInitLCDecl(UO->getSubExpr()) == LCDecl220k
)
8516
219k
      return setStep(SemaRef
8517
219k
                         .ActOnIntegerConstant(UO->getBeginLoc(),
8518
219k
                                               (UO->isDecrementOp() ? 
-1477
:
1219k
))
8519
219k
                         .get(),
8520
219k
                     /*Subtract=*/false);
8521
220k
  } else 
if (auto *9.52k
BO9.52k
= dyn_cast<BinaryOperator>(S)) {
8522
5.60k
    switch (BO->getOpcode()) {
8523
3.25k
    case BO_AddAssign:
8524
4.16k
    case BO_SubAssign:
8525
4.16k
      if (getInitLCDecl(BO->getLHS()) == LCDecl)
8526
4.16k
        return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8527
0
      break;
8528
1.32k
    case BO_Assign:
8529
1.32k
      if (getInitLCDecl(BO->getLHS()) == LCDecl)
8530
1.20k
        return checkAndSetIncRHS(BO->getRHS());
8531
120
      break;
8532
120
    default:
8533
120
      break;
8534
5.60k
    }
8535
5.60k
  } else 
if (auto *3.91k
CE3.91k
= dyn_cast<CXXOperatorCallExpr>(S)) {
8536
3.79k
    switch (CE->getOperator()) {
8537
2.21k
    case OO_PlusPlus:
8538
2.33k
    case OO_MinusMinus:
8539
2.33k
      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8540
2.33k
        return setStep(SemaRef
8541
2.33k
                           .ActOnIntegerConstant(
8542
2.33k
                               CE->getBeginLoc(),
8543
2.33k
                               ((CE->getOperator() == OO_MinusMinus) ? 
-1120
:
12.21k
))
8544
2.33k
                           .get(),
8545
2.33k
                       /*Subtract=*/false);
8546
0
      break;
8547
495
    case OO_PlusEqual:
8548
495
    case OO_MinusEqual:
8549
495
      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8550
495
        return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8551
0
      break;
8552
960
    case OO_Equal:
8553
960
      if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8554
960
        return checkAndSetIncRHS(CE->getArg(1));
8555
0
      break;
8556
0
    default:
8557
0
      break;
8558
3.79k
    }
8559
3.79k
  }
8560
844
  if (dependent() || 
SemaRef.CurContext->isDependentContext()840
)
8561
4
    return false;
8562
840
  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8563
840
      << S->getSourceRange() << LCDecl;
8564
840
  return true;
8565
844
}
8566
8567
static ExprResult
8568
tryBuildCapture(Sema &SemaRef, Expr *Capture,
8569
                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8570
2.34M
                StringRef Name = ".capture_expr.") {
8571
2.34M
  if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8572
13
    return Capture;
8573
2.34M
  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8574
2.18M
    return SemaRef.PerformImplicitConversion(
8575
2.18M
        Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8576
2.18M
        /*AllowExplicit=*/true);
8577
158k
  auto I = Captures.find(Capture);
8578
158k
  if (I != Captures.end())
8579
79.2k
    return buildCapture(SemaRef, Capture, I->second, Name);
8580
79.1k
  DeclRefExpr *Ref = nullptr;
8581
79.1k
  ExprResult Res = buildCapture(SemaRef, Capture, Ref, Name);
8582
79.1k
  Captures[Capture] = Ref;
8583
79.1k
  return Res;
8584
158k
}
8585
8586
/// Calculate number of iterations, transforming to unsigned, if number of
8587
/// iterations may be larger than the original type.
8588
static Expr *
8589
calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8590
                  Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8591
                  bool TestIsStrictOp, bool RoundToStep,
8592
330k
                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8593
330k
  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8594
330k
  if (!NewStep.isUsable())
8595
0
    return nullptr;
8596
330k
  llvm::APSInt LRes, SRes;
8597
330k
  bool IsLowerConst = false, IsStepConst = false;
8598
330k
  if (std::optional<llvm::APSInt> Res =
8599
330k
          Lower->getIntegerConstantExpr(SemaRef.Context)) {
8600
325k
    LRes = *Res;
8601
325k
    IsLowerConst = true;
8602
325k
  }
8603
330k
  if (std::optional<llvm::APSInt> Res =
8604
330k
          Step->getIntegerConstantExpr(SemaRef.Context)) {
8605
328k
    SRes = *Res;
8606
328k
    IsStepConst = true;
8607
328k
  }
8608
330k
  bool NoNeedToConvert = IsLowerConst && 
!RoundToStep325k
&&
8609
330k
                         
(162k
(162k
!TestIsStrictOp162k
&&
LRes.isNonNegative()1.32k
) ||
8610
162k
                          
(161k
TestIsStrictOp161k
&&
LRes.isStrictlyPositive()161k
));
8611
330k
  bool NeedToReorganize = false;
8612
  // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8613
330k
  if (!NoNeedToConvert && 
IsLowerConst321k
&&
8614
330k
      
(316k
TestIsStrictOp316k
||
(797
RoundToStep797
&&
IsStepConst797
))) {
8615
316k
    NoNeedToConvert = true;
8616
316k
    if (RoundToStep) {
8617
162k
      unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8618
162k
                        ? 
LRes.getBitWidth()1.20k
8619
162k
                        : 
SRes.getBitWidth()161k
;
8620
162k
      LRes = LRes.extend(BW + 1);
8621
162k
      LRes.setIsSigned(true);
8622
162k
      SRes = SRes.extend(BW + 1);
8623
162k
      SRes.setIsSigned(true);
8624
162k
      LRes -= SRes;
8625
162k
      NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8626
162k
      LRes = LRes.trunc(BW);
8627
162k
    }
8628
316k
    if (TestIsStrictOp) {
8629
316k
      unsigned BW = LRes.getBitWidth();
8630
316k
      LRes = LRes.extend(BW + 1);
8631
316k
      LRes.setIsSigned(true);
8632
316k
      ++LRes;
8633
316k
      NoNeedToConvert =
8634
316k
          NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8635
      // truncate to the original bitwidth.
8636
316k
      LRes = LRes.trunc(BW);
8637
316k
    }
8638
316k
    NeedToReorganize = NoNeedToConvert;
8639
316k
  }
8640
330k
  llvm::APSInt URes;
8641
330k
  bool IsUpperConst = false;
8642
330k
  if (std::optional<llvm::APSInt> Res =
8643
330k
          Upper->getIntegerConstantExpr(SemaRef.Context)) {
8644
263k
    URes = *Res;
8645
263k
    IsUpperConst = true;
8646
263k
  }
8647
330k
  if (NoNeedToConvert && 
IsLowerConst325k
&&
IsUpperConst325k
&&
8648
330k
      
(262k
!RoundToStep262k
||
IsStepConst131k
)) {
8649
262k
    unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? 
LRes.getBitWidth()308
8650
262k
                                                          : 
URes.getBitWidth()262k
;
8651
262k
    LRes = LRes.extend(BW + 1);
8652
262k
    LRes.setIsSigned(true);
8653
262k
    URes = URes.extend(BW + 1);
8654
262k
    URes.setIsSigned(true);
8655
262k
    URes -= LRes;
8656
262k
    NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8657
262k
    NeedToReorganize = NoNeedToConvert;
8658
262k
  }
8659
  // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8660
  // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8661
  // unsigned.
8662
330k
  if ((!NoNeedToConvert || 
(325k
LRes.isNegative()325k
&&
!IsUpperConst7.11k
)) &&
8663
330k
      
!LCTy->isDependentType()4.98k
&&
LCTy->isIntegerType()4.98k
) {
8664
1.19k
    QualType LowerTy = Lower->getType();
8665
1.19k
    QualType UpperTy = Upper->getType();
8666
1.19k
    uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8667
1.19k
    uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8668
1.19k
    if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8669
1.19k
        
(290
LowerSize > UpperSize290
&&
LowerTy->hasSignedIntegerRepresentation()0
)) {
8670
903
      QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8671
903
          LowerSize > UpperSize ? 
LowerSize0
: UpperSize, /*Signed=*/0);
8672
903
      Upper =
8673
903
          SemaRef
8674
903
              .PerformImplicitConversion(
8675
903
                  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8676
903
                  CastType, Sema::AA_Converting)
8677
903
              .get();
8678
903
      Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8679
903
      NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8680
903
    }
8681
1.19k
  }
8682
330k
  if (!Lower || !Upper || NewStep.isInvalid())
8683
0
    return nullptr;
8684
8685
330k
  ExprResult Diff;
8686
  // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8687
  // 1]).
8688
330k
  if (NeedToReorganize) {
8689
324k
    Diff = Lower;
8690
8691
324k
    if (RoundToStep) {
8692
      // Lower - Step
8693
162k
      Diff =
8694
162k
          SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8695
162k
      if (!Diff.isUsable())
8696
0
        return nullptr;
8697
162k
    }
8698
8699
    // Lower - Step [+ 1]
8700
324k
    if (TestIsStrictOp)
8701
322k
      Diff = SemaRef.BuildBinOp(
8702
322k
          S, DefaultLoc, BO_Add, Diff.get(),
8703
322k
          SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8704
324k
    if (!Diff.isUsable())
8705
0
      return nullptr;
8706
8707
324k
    Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8708
324k
    if (!Diff.isUsable())
8709
0
      return nullptr;
8710
8711
    // Upper - (Lower - Step [+ 1]).
8712
324k
    Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8713
324k
    if (!Diff.isUsable())
8714
0
      return nullptr;
8715
324k
  } else {
8716
5.48k
    Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8717
8718
5.48k
    if (!Diff.isUsable() && 
LCTy->getAsCXXRecordDecl()354
) {
8719
      // BuildBinOp already emitted error, this one is to point user to upper
8720
      // and lower bound, and to tell what is passed to 'operator-'.
8721
350
      SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8722
350
          << Upper->getSourceRange() << Lower->getSourceRange();
8723
350
      return nullptr;
8724
350
    }
8725
8726
5.13k
    if (!Diff.isUsable())
8727
4
      return nullptr;
8728
8729
    // Upper - Lower [- 1]
8730
5.13k
    if (TestIsStrictOp)
8731
4.17k
      Diff = SemaRef.BuildBinOp(
8732
4.17k
          S, DefaultLoc, BO_Sub, Diff.get(),
8733
4.17k
          SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8734
5.13k
    if (!Diff.isUsable())
8735
0
      return nullptr;
8736
8737
5.13k
    if (RoundToStep) {
8738
      // Upper - Lower [- 1] + Step
8739
3.29k
      Diff =
8740
3.29k
          SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8741
3.29k
      if (!Diff.isUsable())
8742
0
        return nullptr;
8743
3.29k
    }
8744
5.13k
  }
8745
8746
  // Parentheses (for dumping/debugging purposes only).
8747
329k
  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8748
329k
  if (!Diff.isUsable())
8749
0
    return nullptr;
8750
8751
  // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8752
329k
  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8753
329k
  if (!Diff.isUsable())
8754
0
    return nullptr;
8755
8756
329k
  return Diff.get();
8757
329k
}
8758
8759
/// Build the expression to calculate the number of iterations.
8760
Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8761
    Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8762
165k
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8763
165k
  QualType VarType = LCDecl->getType().getNonReferenceType();
8764
165k
  if (!VarType->isIntegerType() && 
!VarType->isPointerType()3.07k
&&
8765
165k
      
!SemaRef.getLangOpts().CPlusPlus2.35k
)
8766
0
    return nullptr;
8767
165k
  Expr *LBVal = LB;
8768
165k
  Expr *UBVal = UB;
8769
  // OuterVar = (LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8770
  // max(LB(MinVal), LB(MaxVal)))
8771
165k
  if (InitDependOnLC) {
8772
80
    const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8773
80
    if (!IS.MinValue || !IS.MaxValue)
8774
0
      return nullptr;
8775
    // OuterVar = Min
8776
80
    ExprResult MinValue =
8777
80
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8778
80
    if (!MinValue.isUsable())
8779
0
      return nullptr;
8780
8781
80
    ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8782
80
                                             IS.CounterVar, MinValue.get());
8783
80
    if (!LBMinVal.isUsable())
8784
0
      return nullptr;
8785
    // OuterVar = Min, LBVal
8786
80
    LBMinVal =
8787
80
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8788
80
    if (!LBMinVal.isUsable())
8789
0
      return nullptr;
8790
    // (OuterVar = Min, LBVal)
8791
80
    LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8792
80
    if (!LBMinVal.isUsable())
8793
0
      return nullptr;
8794
8795
    // OuterVar = Max
8796
80
    ExprResult MaxValue =
8797
80
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8798
80
    if (!MaxValue.isUsable())
8799
0
      return nullptr;
8800
8801
80
    ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8802
80
                                             IS.CounterVar, MaxValue.get());
8803
80
    if (!LBMaxVal.isUsable())
8804
0
      return nullptr;
8805
    // OuterVar = Max, LBVal
8806
80
    LBMaxVal =
8807
80
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8808
80
    if (!LBMaxVal.isUsable())
8809
0
      return nullptr;
8810
    // (OuterVar = Max, LBVal)
8811
80
    LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8812
80
    if (!LBMaxVal.isUsable())
8813
0
      return nullptr;
8814
8815
80
    Expr *LBMin =
8816
80
        tryBuildCapture(SemaRef, LBMinVal.get(), Captures, ".lb_min").get();
8817
80
    Expr *LBMax =
8818
80
        tryBuildCapture(SemaRef, LBMaxVal.get(), Captures, ".lb_max").get();
8819
80
    if (!LBMin || !LBMax)
8820
0
      return nullptr;
8821
    // LB(MinVal) < LB(MaxVal)
8822
80
    ExprResult MinLessMaxRes =
8823
80
        SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8824
80
    if (!MinLessMaxRes.isUsable())
8825
0
      return nullptr;
8826
80
    Expr *MinLessMax =
8827
80
        tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures, ".min_less_max")
8828
80
            .get();
8829
80
    if (!MinLessMax)
8830
0
      return nullptr;
8831
80
    if (*TestIsLessOp) {
8832
      // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8833
      // LB(MaxVal))
8834
80
      ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8835
80
                                                    MinLessMax, LBMin, LBMax);
8836
80
      if (!MinLB.isUsable())
8837
0
        return nullptr;
8838
80
      LBVal = MinLB.get();
8839
80
    } else {
8840
      // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8841
      // LB(MaxVal))
8842
0
      ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8843
0
                                                    MinLessMax, LBMax, LBMin);
8844
0
      if (!MaxLB.isUsable())
8845
0
        return nullptr;
8846
0
      LBVal = MaxLB.get();
8847
0
    }
8848
    // OuterVar = LB
8849
80
    LBMinVal =
8850
80
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8851
80
    if (!LBMinVal.isUsable())
8852
0
      return nullptr;
8853
80
    LBVal = LBMinVal.get();
8854
80
  }
8855
  // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8856
  // min(UB(MinVal), UB(MaxVal))
8857
165k
  if (CondDependOnLC) {
8858
64
    const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8859
64
    if (!IS.MinValue || !IS.MaxValue)
8860
0
      return nullptr;
8861
    // OuterVar = Min
8862
64
    ExprResult MinValue =
8863
64
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8864
64
    if (!MinValue.isUsable())
8865
0
      return nullptr;
8866
8867
64
    ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8868
64
                                             IS.CounterVar, MinValue.get());
8869
64
    if (!UBMinVal.isUsable())
8870
0
      return nullptr;
8871
    // OuterVar = Min, UBVal
8872
64
    UBMinVal =
8873
64
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8874
64
    if (!UBMinVal.isUsable())
8875
0
      return nullptr;
8876
    // (OuterVar = Min, UBVal)
8877
64
    UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8878
64
    if (!UBMinVal.isUsable())
8879
0
      return nullptr;
8880
8881
    // OuterVar = Max
8882
64
    ExprResult MaxValue =
8883
64
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8884
64
    if (!MaxValue.isUsable())
8885
0
      return nullptr;
8886
8887
64
    ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8888
64
                                             IS.CounterVar, MaxValue.get());
8889
64
    if (!UBMaxVal.isUsable())
8890
0
      return nullptr;
8891
    // OuterVar = Max, UBVal
8892
64
    UBMaxVal =
8893
64
        SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8894
64
    if (!UBMaxVal.isUsable())
8895
0
      return nullptr;
8896
    // (OuterVar = Max, UBVal)
8897
64
    UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8898
64
    if (!UBMaxVal.isUsable())
8899
0
      return nullptr;
8900
8901
64
    Expr *UBMin =
8902
64
        tryBuildCapture(SemaRef, UBMinVal.get(), Captures, ".ub_min").get();
8903
64
    Expr *UBMax =
8904
64
        tryBuildCapture(SemaRef, UBMaxVal.get(), Captures, ".ub_max").get();
8905
64
    if (!UBMin || !UBMax)
8906
0
      return nullptr;
8907
    // UB(MinVal) > UB(MaxVal)
8908
64
    ExprResult MinGreaterMaxRes =
8909
64
        SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8910
64
    if (!MinGreaterMaxRes.isUsable())
8911
0
      return nullptr;
8912
64
    Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.get(),
8913
64
                                          Captures, ".min_greater_max")
8914
64
                              .get();
8915
64
    if (!MinGreaterMax)
8916
0
      return nullptr;
8917
64
    if (*TestIsLessOp) {
8918
      // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8919
      // UB(MaxVal))
8920
64
      ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8921
64
          DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8922
64
      if (!MaxUB.isUsable())
8923
0
        return nullptr;
8924
64
      UBVal = MaxUB.get();
8925
64
    } else {
8926
      // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8927
      // UB(MaxVal))
8928
0
      ExprResult MinUB = SemaRef.ActOnConditionalOp(
8929
0
          DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8930
0
      if (!MinUB.isUsable())
8931
0
        return nullptr;
8932
0
      UBVal = MinUB.get();
8933
0
    }
8934
64
  }
8935
165k
  Expr *UBExpr = *TestIsLessOp ? 
UBVal164k
:
LBVal1.12k
;
8936
165k
  Expr *LBExpr = *TestIsLessOp ? 
LBVal164k
:
UBVal1.12k
;
8937
165k
  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures, ".upper").get();
8938
165k
  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures, ".lower").get();
8939
165k
  if (!Upper || !Lower)
8940
0
    return nullptr;
8941
8942
165k
  ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8943
165k
                                      Step, VarType, TestIsStrictOp,
8944
165k
                                      /*RoundToStep=*/true, Captures);
8945
165k
  if (!Diff.isUsable())
8946
352
    return nullptr;
8947
8948
  // OpenMP runtime requires 32-bit or 64-bit loop variables.
8949
165k
  QualType Type = Diff.get()->getType();
8950
165k
  ASTContext &C = SemaRef.Context;
8951
165k
  bool UseVarType = VarType->hasIntegerRepresentation() &&
8952
165k
                    
C.getTypeSize(Type) > C.getTypeSize(VarType)162k
;
8953
165k
  if (!Type->isIntegerType() || 
UseVarType165k
) {
8954
1.34k
    unsigned NewSize =
8955
1.34k
        UseVarType ? 
C.getTypeSize(VarType)1.00k
:
C.getTypeSize(Type)334
;
8956
1.34k
    bool IsSigned = UseVarType ? 
VarType->hasSignedIntegerRepresentation()1.00k
8957
1.34k
                               : 
Type->hasSignedIntegerRepresentation()334
;
8958
1.34k
    Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8959
1.34k
    if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8960
1.34k
      Diff = SemaRef.PerformImplicitConversion(
8961
1.34k
          Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8962
1.34k
      if (!Diff.isUsable())
8963
0
        return nullptr;
8964
1.34k
    }
8965
1.34k
  }
8966
165k
  if (LimitedType) {
8967
150k
    unsigned NewSize = (C.getTypeSize(Type) > 32) ? 
641.42k
:
32149k
;
8968
150k
    if (NewSize != C.getTypeSize(Type)) {
8969
702
      if (NewSize < C.getTypeSize(Type)) {
8970
26
        assert(NewSize == 64 && "incorrect loop var size");
8971
26
        SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8972
26
            << InitSrcRange << ConditionSrcRange;
8973
26
      }
8974
702
      QualType NewType = C.getIntTypeForBitwidth(
8975
702
          NewSize, Type->hasSignedIntegerRepresentation() ||
8976
702
                       
C.getTypeSize(Type) < NewSize135
);
8977
702
      if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8978
702
        Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8979
702
                                                 Sema::AA_Converting, true);
8980
702
        if (!Diff.isUsable())
8981
0
          return nullptr;
8982
702
      }
8983
702
    }
8984
150k
  }
8985
8986
165k
  return Diff.get();
8987
165k
}
8988
8989
std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8990
165k
    Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8991
  // Do not build for iterators, they cannot be used in non-rectangular loop
8992
  // nests.
8993
165k
  if (LCDecl->getType()->isRecordType())
8994
2.35k
    return std::make_pair(nullptr, nullptr);
8995
  // If we subtract, the min is in the condition, otherwise the min is in the
8996
  // init value.
8997
163k
  Expr *MinExpr = nullptr;
8998
163k
  Expr *MaxExpr = nullptr;
8999
163k
  Expr *LBExpr = *TestIsLessOp ? 
LB162k
:
UB885
;
9000
163k
  Expr *UBExpr = *TestIsLessOp ? 
UB162k
:
LB885
;
9001
163k
  bool LBNonRect =
9002
163k
      *TestIsLessOp ? 
InitDependOnLC.has_value()162k
:
CondDependOnLC.has_value()885
;
9003
163k
  bool UBNonRect =
9004
163k
      *TestIsLessOp ? 
CondDependOnLC.has_value()162k
:
InitDependOnLC.has_value()885
;
9005
163k
  Expr *Lower =
9006
163k
      LBNonRect ? 
LBExpr80
:
tryBuildCapture(SemaRef, LBExpr, Captures).get()163k
;
9007
163k
  Expr *Upper =
9008
163k
      UBNonRect ? 
UBExpr64
:
tryBuildCapture(SemaRef, UBExpr, Captures).get()163k
;
9009
163k
  if (!Upper || !Lower)
9010
0
    return std::make_pair(nullptr, nullptr);
9011
9012
163k
  if (*TestIsLessOp)
9013
162k
    MinExpr = Lower;
9014
885
  else
9015
885
    MaxExpr = Upper;
9016
9017
  // Build minimum/maximum value based on number of iterations.
9018
163k
  QualType VarType = LCDecl->getType().getNonReferenceType();
9019
9020
163k
  ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
9021
163k
                                      Step, VarType, TestIsStrictOp,
9022
163k
                                      /*RoundToStep=*/false, Captures);
9023
163k
  if (!Diff.isUsable())
9024
2
    return std::make_pair(nullptr, nullptr);
9025
9026
  // ((Upper - Lower [- 1]) / Step) * Step
9027
  // Parentheses (for dumping/debugging purposes only).
9028
163k
  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
9029
163k
  if (!Diff.isUsable())
9030
0
    return std::make_pair(nullptr, nullptr);
9031
9032
163k
  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
9033
163k
  if (!NewStep.isUsable())
9034
0
    return std::make_pair(nullptr, nullptr);
9035
163k
  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
9036
163k
  if (!Diff.isUsable())
9037
0
    return std::make_pair(nullptr, nullptr);
9038
9039
  // Parentheses (for dumping/debugging purposes only).
9040
163k
  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
9041
163k
  if (!Diff.isUsable())
9042
0
    return std::make_pair(nullptr, nullptr);
9043
9044
  // Convert to the ptrdiff_t, if original type is pointer.
9045
163k
  if (VarType->isAnyPointerType() &&
9046
163k
      !SemaRef.Context.hasSameType(
9047
718
          Diff.get()->getType(),
9048
718
          SemaRef.Context.getUnsignedPointerDiffType())) {
9049
718
    Diff = SemaRef.PerformImplicitConversion(
9050
718
        Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
9051
718
        Sema::AA_Converting, /*AllowExplicit=*/true);
9052
718
  }
9053
163k
  if (!Diff.isUsable())
9054
0
    return std::make_pair(nullptr, nullptr);
9055
9056
163k
  if (*TestIsLessOp) {
9057
    // MinExpr = Lower;
9058
    // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
9059
162k
    Diff = SemaRef.BuildBinOp(
9060
162k
        S, DefaultLoc, BO_Add,
9061
162k
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
9062
162k
        Diff.get());
9063
162k
    if (!Diff.isUsable())
9064
0
      return std::make_pair(nullptr, nullptr);
9065
162k
  } else {
9066
    // MaxExpr = Upper;
9067
    // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
9068
885
    Diff = SemaRef.BuildBinOp(
9069
885
        S, DefaultLoc, BO_Sub,
9070
885
        SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
9071
885
        Diff.get());
9072
885
    if (!Diff.isUsable())
9073
0
      return std::make_pair(nullptr, nullptr);
9074
885
  }
9075
9076
  // Convert to the original type.
9077
163k
  if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
9078
161k
    Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
9079
161k
                                             Sema::AA_Converting,
9080
161k
                                             /*AllowExplicit=*/true);
9081
163k
  if (!Diff.isUsable())
9082
0
    return std::make_pair(nullptr, nullptr);
9083
9084
163k
  Sema::TentativeAnalysisScope Trap(SemaRef);
9085
163k
  Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
9086
163k
  if (!Diff.isUsable())
9087
0
    return std::make_pair(nullptr, nullptr);
9088
9089
163k
  if (*TestIsLessOp)
9090
162k
    MaxExpr = Diff.get();
9091
885
  else
9092
885
    MinExpr = Diff.get();
9093
9094
163k
  return std::make_pair(MinExpr, MaxExpr);
9095
163k
}
9096
9097
165k
Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
9098
165k
  if (InitDependOnLC || 
CondDependOnLC165k
)
9099
91
    return Condition;
9100
165k
  return nullptr;
9101
165k
}
9102
9103
Expr *OpenMPIterationSpaceChecker::buildPreCond(
9104
    Scope *S, Expr *Cond,
9105
165k
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
9106
  // Do not build a precondition when the condition/initialization is dependent
9107
  // to prevent pessimistic early loop exit.
9108
  // TODO: this can be improved by calculating min/max values but not sure that
9109
  // it will be very effective.
9110
165k
  if (CondDependOnLC || 
InitDependOnLC165k
)
9111
91
    return SemaRef
9112
91
        .PerformImplicitConversion(
9113
91
            SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
9114
91
            SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
9115
91
            /*AllowExplicit=*/true)
9116
91
        .get();
9117
9118
  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
9119
165k
  Sema::TentativeAnalysisScope Trap(SemaRef);
9120
9121
165k
  ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
9122
165k
  ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
9123
165k
  if (!NewLB.isUsable() || !NewUB.isUsable())
9124
0
    return nullptr;
9125
9126
165k
  ExprResult CondExpr =
9127
165k
      SemaRef.BuildBinOp(S, DefaultLoc,
9128
165k
                         *TestIsLessOp ? 
(164k
TestIsStrictOp164k
?
BO_LT164k
:
BO_LE520
)
9129
165k
                                       : 
(1.12k
TestIsStrictOp1.12k
?
BO_GT457
:
BO_GE668
),
9130
165k
                         NewLB.get(), NewUB.get());
9131
165k
  if (CondExpr.isUsable()) {
9132
165k
    if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
9133
165k
                                                SemaRef.Context.BoolTy))
9134
9.66k
      CondExpr = SemaRef.PerformImplicitConversion(
9135
9.66k
          CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
9136
9.66k
          /*AllowExplicit=*/true);
9137
165k
  }
9138
9139
  // Otherwise use original loop condition and evaluate it in runtime.
9140
165k
  return CondExpr.isUsable() ? 
CondExpr.get()165k
:
Cond486
;
9141
165k
}
9142
9143
/// Build reference expression to the counter be used for codegen.
9144
DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
9145
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9146
165k
    DSAStackTy &DSA) const {
9147
165k
  auto *VD = dyn_cast<VarDecl>(LCDecl);
9148
165k
  if (!VD) {
9149
156
    VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
9150
156
    DeclRefExpr *Ref = buildDeclRefExpr(
9151
156
        SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
9152
156
    const DSAStackTy::DSAVarData Data =
9153
156
        DSA.getTopDSA(LCDecl, /*FromParent=*/false);
9154
    // If the loop control decl is explicitly marked as private, do not mark it
9155
    // as captured again.
9156
156
    if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
9157
0
      Captures.insert(std::make_pair(LCRef, Ref));
9158
156
    return Ref;
9159
156
  }
9160
165k
  return cast<DeclRefExpr>(LCRef);
9161
165k
}
9162
9163
165k
Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
9164
165k
  if (LCDecl && !LCDecl->isInvalidDecl()) {
9165
165k
    QualType Type = LCDecl->getType().getNonReferenceType();
9166
165k
    VarDecl *PrivateVar = buildVarDecl(
9167
165k
        SemaRef, DefaultLoc, Type, LCDecl->getName(),
9168
165k
        LCDecl->hasAttrs() ? 
&LCDecl->getAttrs()180
:
nullptr165k
,
9169
165k
        isa<VarDecl>(LCDecl)
9170
165k
            ? 
buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)165k
9171
165k
            : 
nullptr156
);
9172
165k
    if (PrivateVar->isInvalidDecl())
9173
0
      return nullptr;
9174
165k
    return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
9175
165k
  }
9176
0
  return nullptr;
9177
165k
}
9178
9179
/// Build initialization of the counter to be used for codegen.
9180
165k
Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
9181
9182
/// Build step of the counter be used for codegen.
9183
165k
Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
9184
9185
Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9186
    Scope *S, Expr *Counter,
9187
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
9188
538
    Expr *Inc, OverloadedOperatorKind OOK) {
9189
538
  Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
9190
538
  if (!Cnt)
9191
0
    return nullptr;
9192
538
  if (Inc) {
9193
166
    assert((OOK == OO_Plus || OOK == OO_Minus) &&
9194
166
           "Expected only + or - operations for depend clauses.");
9195
166
    BinaryOperatorKind BOK = (OOK == OO_Plus) ? 
BO_Add48
:
BO_Sub118
;
9196
166
    Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
9197
166
    if (!Cnt)
9198
0
      return nullptr;
9199
166
  }
9200
538
  QualType VarType = LCDecl->getType().getNonReferenceType();
9201
538
  if (!VarType->isIntegerType() && 
!VarType->isPointerType()0
&&
9202
538
      
!SemaRef.getLangOpts().CPlusPlus0
)
9203
0
    return nullptr;
9204
  // Upper - Lower
9205
538
  Expr *Upper =
9206
538
      *TestIsLessOp ? 
Cnt526
:
tryBuildCapture(SemaRef, LB, Captures).get()12
;
9207
538
  Expr *Lower =
9208
538
      *TestIsLessOp ? 
tryBuildCapture(SemaRef, LB, Captures).get()526
:
Cnt12
;
9209
538
  if (!Upper || !Lower)
9210
0
    return nullptr;
9211
9212
538
  ExprResult Diff = calculateNumIters(
9213
538
      SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9214
538
      /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
9215
538
  if (!Diff.isUsable())
9216
0
    return nullptr;
9217
9218
538
  return Diff.get();
9219
538
}
9220
} // namespace
9221
9222
268k
void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
9223
268k
  assert(getLangOpts().OpenMP && "OpenMP is not active.");
9224
268k
  assert(Init && "Expected loop in canonical form.");
9225
268k
  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
9226
268k
  if (AssociatedLoops > 0 &&
9227
268k
      
isOpenMPLoopDirective(263k
DSAStack263k
->getCurrentDirective())) {
9228
261k
    DSAStack->loopStart();
9229
261k
    OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
9230
261k
                                    *DSAStack, ForLoc);
9231
261k
    if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
9232
261k
      if (ValueDecl *D = ISC.getLoopDecl()) {
9233
261k
        auto *VD = dyn_cast<VarDecl>(D);
9234
261k
        DeclRefExpr *PrivateRef = nullptr;
9235
261k
        if (!VD) {
9236
210
          if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
9237
24
            VD = Private;
9238
186
          } else {
9239
186
            PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
9240
186
                                      /*WithInit=*/false);
9241
186
            VD = cast<VarDecl>(PrivateRef->getDecl());
9242
186
          }
9243
210
        }
9244
261k
        DSAStack->addLoopControlVariable(D, VD);
9245
261k
        const Decl *LD = DSAStack->getPossiblyLoopCunter();
9246
261k
        if (LD != D->getCanonicalDecl()) {
9247
224k
          DSAStack->resetPossibleLoopCounter();
9248
224k
          if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
9249
17.4k
            MarkDeclarationsReferencedInExpr(
9250
17.4k
                buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
9251
17.4k
                                 Var->getType().getNonLValueExprType(Context),
9252
17.4k
                                 ForLoc, /*RefersToCapture=*/true));
9253
224k
        }
9254
261k
        OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9255
        // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9256
        // Referenced in a Construct, C/C++]. The loop iteration variable in the
9257
        // associated for-loop of a simd construct with just one associated
9258
        // for-loop may be listed in a linear clause with a constant-linear-step
9259
        // that is the increment of the associated for-loop. The loop iteration
9260
        // variable(s) in the associated for-loop(s) of a for or parallel for
9261
        // construct may be listed in a private or lastprivate clause.
9262
261k
        DSAStackTy::DSAVarData DVar =
9263
261k
            DSAStack->getTopDSA(D, /*FromParent=*/false);
9264
        // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9265
        // is declared in the loop and it is predetermined as a private.
9266
261k
        Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9267
261k
        OpenMPClauseKind PredeterminedCKind =
9268
261k
            isOpenMPSimdDirective(DKind)
9269
261k
                ? 
(149k
DSAStack149k
->hasMutipleLoops()149k
?
OMPC_lastprivate3.09k
:
OMPC_linear145k
)
9270
261k
                : 
OMPC_private111k
;
9271
261k
        if (((isOpenMPSimdDirective(DKind) && 
DVar.CKind != OMPC_unknown149k
&&
9272
261k
              
DVar.CKind != PredeterminedCKind993
&&
DVar.RefExpr510
&&
9273
261k
              
(498
LangOpts.OpenMP <= 45498
||
(326
DVar.CKind != OMPC_lastprivate326
&&
9274
326
                                         
DVar.CKind != OMPC_private274
))) ||
9275
261k
             
(260k
(260k
isOpenMPWorksharingDirective(DKind)260k
||
DKind == OMPD_taskloop138k
||
9276
260k
               
DKind == OMPD_master_taskloop128k
||
DKind == OMPD_masked_taskloop121k
||
9277
260k
               
DKind == OMPD_parallel_master_taskloop117k
||
9278
260k
               
DKind == OMPD_parallel_masked_taskloop112k
||
9279
260k
               
isOpenMPDistributeDirective(DKind)107k
) &&
9280
260k
              
!isOpenMPSimdDirective(DKind)201k
&&
DVar.CKind != OMPC_unknown111k
&&
9281
260k
              
DVar.CKind != OMPC_private450
&&
DVar.CKind != OMPC_lastprivate370
)) &&
9282
261k
            
(634
DVar.CKind != OMPC_private634
||
DVar.RefExpr38
)) {
9283
634
          Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9284
634
              << getOpenMPClauseName(DVar.CKind)
9285
634
              << getOpenMPDirectiveName(DKind)
9286
634
              << getOpenMPClauseName(PredeterminedCKind);
9287
634
          if (DVar.RefExpr == nullptr)
9288
0
            DVar.CKind = PredeterminedCKind;
9289
634
          reportOriginalDsa(*this, DSAStack, D, DVar,
9290
634
                            /*IsLoopIterVar=*/true);
9291
260k
        } else if (LoopDeclRefExpr) {
9292
          // Make the loop iteration variable private (for worksharing
9293
          // constructs), linear (for simd directives with the only one
9294
          // associated loop) or lastprivate (for simd directives with several
9295
          // collapsed or ordered loops).
9296
260k
          if (DVar.CKind == OMPC_unknown)
9297
259k
            DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9298
259k
                             PrivateRef);
9299
260k
        }
9300
261k
      }
9301
261k
    }
9302
261k
    DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9303
261k
  }
9304
268k
}
9305
9306
namespace {
9307
// Utility for openmp doacross clause kind
9308
class OMPDoacrossKind {
9309
public:
9310
219
  bool isSource(const OMPDoacrossClause *C) {
9311
219
    return C->getDependenceType() == OMPC_DOACROSS_source ||
9312
219
           
C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration153
;
9313
219
  }
9314
193
  bool isSink(const OMPDoacrossClause *C) {
9315
193
    return C->getDependenceType() == OMPC_DOACROSS_sink;
9316
193
  }
9317
73
  bool isSinkIter(const OMPDoacrossClause *C) {
9318
73
    return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
9319
73
  }
9320
};
9321
} // namespace
9322
/// Called on a for stmt to check and extract its iteration space
9323
/// for further processing (such as collapsing).
9324
static bool checkOpenMPIterationSpace(
9325
    OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
9326
    unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
9327
    unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
9328
    Expr *OrderedLoopCountExpr,
9329
    Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9330
    llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
9331
233k
    llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9332
233k
  bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
9333
  // OpenMP [2.9.1, Canonical Loop Form]
9334
  //   for (init-expr; test-expr; incr-expr) structured-block
9335
  //   for (range-decl: range-expr) structured-block
9336
233k
  if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9337
0
    S = CanonLoop->getLoopStmt();
9338
233k
  auto *For = dyn_cast_or_null<ForStmt>(S);
9339
233k
  auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9340
  // Ranged for is supported only in OpenMP 5.0.
9341
233k
  if (!For && 
(2.53k
SemaRef.LangOpts.OpenMP <= 452.53k
||
!CXXFor2.20k
)) {
9342
2.41k
    OpenMPDirectiveKind DK = (SemaRef.getLangOpts().OpenMP < 50 ||
9343
2.41k
                              
DSA.getMappedDirective() == OMPD_unknown2.08k
)
9344
2.41k
                                 ? 
DKind2.41k
9345
2.41k
                                 : 
DSA.getMappedDirective()3
;
9346
2.41k
    SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
9347
2.41k
        << (CollapseLoopCountExpr != nullptr || 
OrderedLoopCountExpr != nullptr693
)
9348
2.41k
        << getOpenMPDirectiveName(DK) << TotalNestedLoopCount
9349
2.41k
        << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9350
2.41k
    if (TotalNestedLoopCount > 1) {
9351
1.83k
      if (CollapseLoopCountExpr && 
OrderedLoopCountExpr1.72k
)
9352
0
        SemaRef.Diag(DSA.getConstructLoc(),
9353
0
                     diag::note_omp_collapse_ordered_expr)
9354
0
            << 2 << CollapseLoopCountExpr->getSourceRange()
9355
0
            << OrderedLoopCountExpr->getSourceRange();
9356
1.83k
      else if (CollapseLoopCountExpr)
9357
1.72k
        SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9358
1.72k
                     diag::note_omp_collapse_ordered_expr)
9359
1.72k
            << 0 << CollapseLoopCountExpr->getSourceRange();
9360
115
      else
9361
115
        SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9362
115
                     diag::note_omp_collapse_ordered_expr)
9363
115
            << 1 << OrderedLoopCountExpr->getSourceRange();
9364
1.83k
    }
9365
2.41k
    return true;
9366
2.41k
  }
9367
230k
  assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9368
230k
         "No loop body.");
9369
  // Postpone analysis in dependent contexts for ranged for loops.
9370
230k
  if (CXXFor && 
SemaRef.CurContext->isDependentContext()119
)
9371
4
    return false;
9372
9373
230k
  OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9374
230k
                                  For ? 
For->getForLoc()230k
:
CXXFor->getForLoc()115
);
9375
9376
  // Check init.
9377
230k
  Stmt *Init = For ? 
For->getInit()230k
:
CXXFor->getBeginStmt()115
;
9378
230k
  if (ISC.checkAndSetInit(Init))
9379
960
    return true;
9380
9381
229k
  bool HasErrors = false;
9382
9383
  // Check loop variable's type.
9384
229k
  if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
9385
    // OpenMP [2.6, Canonical Loop Form]
9386
    // Var is one of the following:
9387
    //   A variable of signed or unsigned integer type.
9388
    //   For C++, a variable of a random access iterator type.
9389
    //   For C, a variable of a pointer type.
9390
229k
    QualType VarType = LCDecl->getType().getNonReferenceType();
9391
229k
    if (!VarType->isDependentType() && 
!VarType->isIntegerType()223k
&&
9392
229k
        
!VarType->isPointerType()4.91k
&&
9393
229k
        
!(4.19k
SemaRef.getLangOpts().CPlusPlus4.19k
&&
VarType->isOverloadableType()4.03k
)) {
9394
404
      SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9395
404
          << SemaRef.getLangOpts().CPlusPlus;
9396
404
      HasErrors = true;
9397
404
    }
9398
9399
    // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9400
    // a Construct
9401
    // The loop iteration variable(s) in the associated for-loop(s) of a for or
9402
    // parallel for construct is (are) private.
9403
    // The loop iteration variable in the associated for-loop of a simd
9404
    // construct with just one associated for-loop is linear with a
9405
    // constant-linear-step that is the increment of the associated for-loop.
9406
    // Exclude loop var from the list of variables with implicitly defined data
9407
    // sharing attributes.
9408
229k
    VarsWithImplicitDSA.erase(LCDecl);
9409
9410
229k
    assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
9411
9412
    // Check test-expr.
9413
229k
    HasErrors |= ISC.checkAndSetCond(For ? 
For->getCond()229k
:
CXXFor->getCond()115
);
9414
9415
    // Check incr-expr.
9416
229k
    HasErrors |= ISC.checkAndSetInc(For ? 
For->getInc()229k
:
CXXFor->getInc()115
);
9417
229k
  }
9418
9419
229k
  if (ISC.dependent() || 
SemaRef.CurContext->isDependentContext()214k
||
HasErrors170k
)
9420
64.0k
    return HasErrors;
9421
9422
  // Build the loop's iteration space representation.
9423
165k
  ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9424
165k
      DSA.getCurScope(), For ? 
For->getCond()165k
:
CXXFor->getCond()115
, Captures);
9425
165k
  ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9426
165k
      ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9427
165k
                             (isOpenMPWorksharingDirective(DKind) ||
9428
165k
                              
isOpenMPGenericLoopDirective(DKind)87.6k
||
9429
165k
                              
isOpenMPTaskLoopDirective(DKind)87.6k
||
9430
165k
                              
isOpenMPDistributeDirective(DKind)45.2k
||
9431
165k
                              
isOpenMPLoopTransformationDirective(DKind)14.7k
),
9432
165k
                             Captures);
9433
165k
  ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9434
165k
      ISC.buildCounterVar(Captures, DSA);
9435
165k
  ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9436
165k
      ISC.buildPrivateCounterVar();
9437
165k
  ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9438
165k
  ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9439
165k
  ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9440
165k
  ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9441
165k
      ISC.getConditionSrcRange();
9442
165k
  ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9443
165k
      ISC.getIncrementSrcRange();
9444
165k
  ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9445
165k
  ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9446
165k
      ISC.isStrictTestOp();
9447
165k
  std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9448
165k
           ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9449
165k
      ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9450
165k
  ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9451
165k
      ISC.buildFinalCondition(DSA.getCurScope());
9452
165k
  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9453
165k
      ISC.doesInitDependOnLC();
9454
165k
  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9455
165k
      ISC.doesCondDependOnLC();
9456
165k
  ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9457
165k
      ISC.getLoopDependentIdx();
9458
9459
165k
  HasErrors |=
9460
165k
      (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
9461
165k
       ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
9462
165k
       
ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr165k
||
9463
165k
       
ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr165k
||
9464
165k
       
ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr165k
||
9465
165k
       
ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr165k
);
9466
165k
  if (!HasErrors && 
DSA.isOrderedRegion()165k
) {
9467
1.15k
    if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9468
557
      if (CurrentNestedLoopCount <
9469
557
          DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9470
539
        DSA.getOrderedRegionParam().second->setLoopNumIterations(
9471
539
            CurrentNestedLoopCount,
9472
539
            ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9473
539
        DSA.getOrderedRegionParam().second->setLoopCounter(
9474
539
            CurrentNestedLoopCount,
9475
539
            ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9476
539
      }
9477
557
    }
9478
1.15k
    for (auto &Pair : DSA.getDoacrossDependClauses()) {
9479
704
      auto *DependC = dyn_cast<OMPDependClause>(Pair.first);
9480
704
      auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first);
9481
704
      unsigned NumLoops =
9482
704
          DependC ? 
DependC->getNumLoops()582
:
DoacrossC->getNumLoops()122
;
9483
704
      if (CurrentNestedLoopCount >= NumLoops) {
9484
        // Erroneous case - clause has some problems.
9485
12
        continue;
9486
12
      }
9487
692
      if (DependC && 
DependC->getDependencyKind() == OMPC_DEPEND_sink570
&&
9488
692
          
Pair.second.size() <= CurrentNestedLoopCount380
) {
9489
        // Erroneous case - clause has some problems.
9490
132
        DependC->setLoopData(CurrentNestedLoopCount, nullptr);
9491
132
        continue;
9492
132
      }
9493
560
      OMPDoacrossKind ODK;
9494
560
      if (DoacrossC && 
ODK.isSink(DoacrossC)122
&&
9495
560
          
Pair.second.size() <= CurrentNestedLoopCount63
) {
9496
        // Erroneous case - clause has some problems.
9497
22
        DoacrossC->setLoopData(CurrentNestedLoopCount, nullptr);
9498
22
        continue;
9499
22
      }
9500
538
      Expr *CntValue;
9501
538
      SourceLocation DepLoc =
9502
538
          DependC ? 
DependC->getDependencyLoc()438
:
DoacrossC->getDependenceLoc()100
;
9503
538
      if ((DependC && 
DependC->getDependencyKind() == OMPC_DEPEND_source438
) ||
9504
538
          
(348
DoacrossC348
&&
ODK.isSource(DoacrossC)100
))
9505
234
        CntValue = ISC.buildOrderedLoopData(
9506
234
            DSA.getCurScope(),
9507
234
            ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9508
234
            DepLoc);
9509
304
      else if (DoacrossC && 
ODK.isSinkIter(DoacrossC)56
) {
9510
15
        Expr *Cnt = SemaRef
9511
15
                        .DefaultLvalueConversion(
9512
15
                            ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
9513
15
                        .get();
9514
15
        if (!Cnt)
9515
0
          continue;
9516
        // build CounterVar - 1
9517
15
        Expr *Inc =
9518
15
            SemaRef.ActOnIntegerConstant(DoacrossC->getColonLoc(), /*Val=*/1)
9519
15
                .get();
9520
15
        CntValue = ISC.buildOrderedLoopData(
9521
15
            DSA.getCurScope(),
9522
15
            ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9523
15
            DepLoc, Inc, clang::OO_Minus);
9524
15
      } else
9525
289
        CntValue = ISC.buildOrderedLoopData(
9526
289
            DSA.getCurScope(),
9527
289
            ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9528
289
            DepLoc, Pair.second[CurrentNestedLoopCount].first,
9529
289
            Pair.second[CurrentNestedLoopCount].second);
9530
538
      if (DependC)
9531
438
        DependC->setLoopData(CurrentNestedLoopCount, CntValue);
9532
100
      else
9533
100
        DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue);
9534
538
    }
9535
1.15k
  }
9536
9537
165k
  return HasErrors;
9538
229k
}
9539
9540
/// Build 'VarRef = Start.
9541
static ExprResult
9542
buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9543
                 ExprResult Start, bool IsNonRectangularLB,
9544
164k
                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9545
  // Build 'VarRef = Start.
9546
164k
  ExprResult NewStart = IsNonRectangularLB
9547
164k
                            ? 
Start.get()80
9548
164k
                            : 
tryBuildCapture(SemaRef, Start.get(), Captures)164k
;
9549
164k
  if (!NewStart.isUsable())
9550
0
    return ExprError();
9551
164k
  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9552
164k
                                   VarRef.get()->getType())) {
9553
250
    NewStart = SemaRef.PerformImplicitConversion(
9554
250
        NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9555
250
        /*AllowExplicit=*/true);
9556
250
    if (!NewStart.isUsable())
9557
0
      return ExprError();
9558
250
  }
9559
9560
164k
  ExprResult Init =
9561
164k
      SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9562
164k
  return Init;
9563
164k
}
9564
9565
/// Build 'VarRef = Start + Iter * Step'.
9566
static ExprResult buildCounterUpdate(
9567
    Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9568
    ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9569
    bool IsNonRectangularLB,
9570
331k
    llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9571
  // Add parentheses (for debugging purposes only).
9572
331k
  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9573
331k
  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9574
331k
      !Step.isUsable())
9575
0
    return ExprError();
9576
9577
331k
  ExprResult NewStep = Step;
9578
331k
  if (Captures)
9579
327k
    NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9580
331k
  if (NewStep.isInvalid())
9581
0
    return ExprError();
9582
331k
  ExprResult Update =
9583
331k
      SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9584
331k
  if (!Update.isUsable())
9585
0
    return ExprError();
9586
9587
  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9588
  // 'VarRef = Start (+|-) Iter * Step'.
9589
331k
  if (!Start.isUsable())
9590
0
    return ExprError();
9591
331k
  ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9592
331k
  if (!NewStart.isUsable())
9593
0
    return ExprError();
9594
331k
  if (Captures && 
!IsNonRectangularLB327k
)
9595
327k
    NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9596
331k
  if (NewStart.isInvalid())
9597
0
    return ExprError();
9598
9599
  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9600
331k
  ExprResult SavedUpdate = Update;
9601
331k
  ExprResult UpdateVal;
9602
331k
  if (VarRef.get()->getType()->isOverloadableType() ||
9603
331k
      
NewStart.get()->getType()->isOverloadableType()327k
||
9604
331k
      
Update.get()->getType()->isOverloadableType()327k
) {
9605
3.80k
    Sema::TentativeAnalysisScope Trap(SemaRef);
9606
9607
3.80k
    Update =
9608
3.80k
        SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9609
3.80k
    if (Update.isUsable()) {
9610
3.80k
      UpdateVal =
9611
3.80k
          SemaRef.BuildBinOp(S, Loc, Subtract ? 
BO_SubAssign480
:
BO_AddAssign3.32k
,
9612
3.80k
                             VarRef.get(), SavedUpdate.get());
9613
3.80k
      if (UpdateVal.isUsable()) {
9614
3.20k
        Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9615
3.20k
                                            UpdateVal.get());
9616
3.20k
      }
9617
3.80k
    }
9618
3.80k
  }
9619
9620
  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9621
331k
  if (!Update.isUsable() || !UpdateVal.isUsable()) {
9622
328k
    Update = SemaRef.BuildBinOp(S, Loc, Subtract ? 
BO_Sub1.99k
:
BO_Add326k
,
9623
328k
                                NewStart.get(), SavedUpdate.get());
9624
328k
    if (!Update.isUsable())
9625
220
      return ExprError();
9626
9627
327k
    if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9628
327k
                                     VarRef.get()->getType())) {
9629
4.41k
      Update = SemaRef.PerformImplicitConversion(
9630
4.41k
          Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9631
4.41k
      if (!Update.isUsable())
9632
0
        return ExprError();
9633
4.41k
    }
9634
9635
327k
    Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9636
327k
  }
9637
331k
  return Update;
9638
331k
}
9639
9640
/// Convert integer expression \a E to make it have at least \a Bits
9641
/// bits.
9642
323k
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9643
323k
  if (E == nullptr)
9644
0
    return ExprError();
9645
323k
  ASTContext &C = SemaRef.Context;
9646
323k
  QualType OldType = E->getType();
9647
323k
  unsigned HasBits = C.getTypeSize(OldType);
9648
323k
  if (HasBits >= Bits)
9649
163k
    return ExprResult(E);
9650
  // OK to convert to signed, because new type has more bits than old.
9651
160k
  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9652
160k
  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9653
160k
                                           true);
9654
323k
}
9655
9656
/// Check if the given expression \a E is a constant integer that fits
9657
/// into \a Bits bits.
9658
1.37k
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9659
1.37k
  if (E == nullptr)
9660
0
    return false;
9661
1.37k
  if (std::optional<llvm::APSInt> Result =
9662
1.37k
          E->getIntegerConstantExpr(SemaRef.Context))
9663
964
    return Signed ? 
Result->isSignedIntN(Bits)930
:
Result->isIntN(Bits)34
;
9664
412
  return false;
9665
1.37k
}
9666
9667
/// Build preinits statement for the given declarations.
9668
static Stmt *buildPreInits(ASTContext &Context,
9669
184k
                           MutableArrayRef<Decl *> PreInits) {
9670
184k
  if (!PreInits.empty()) {
9671
41.4k
    return new (Context) DeclStmt(
9672
41.4k
        DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9673
41.4k
        SourceLocation(), SourceLocation());
9674
41.4k
  }
9675
143k
  return nullptr;
9676
184k
}
9677
9678
/// Build preinits statement for the given declarations.
9679
static Stmt *
9680
buildPreInits(ASTContext &Context,
9681
171k
              const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9682
171k
  if (!Captures.empty()) {
9683
40.7k
    SmallVector<Decl *, 16> PreInits;
9684
40.7k
    for (const auto &Pair : Captures)
9685
78.0k
      PreInits.push_back(Pair.second->getDecl());
9686
40.7k
    return buildPreInits(Context, PreInits);
9687
40.7k
  }
9688
130k
  return nullptr;
9689
171k
}
9690
9691
/// Build postupdate expression for the given list of postupdates expressions.
9692
78.8k
static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9693
78.8k
  Expr *PostUpdate = nullptr;
9694
78.8k
  if (!PostUpdates.empty()) {
9695
60
    for (Expr *E : PostUpdates) {
9696
60
      Expr *ConvE = S.BuildCStyleCastExpr(
9697
60
                         E->getExprLoc(),
9698
60
                         S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9699
60
                         E->getExprLoc(), E)
9700
60
                        .get();
9701
60
      PostUpdate = PostUpdate
9702
60
                       ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9703
0
                                              PostUpdate, ConvE)
9704
0
                             .get()
9705
60
                       : ConvE;
9706
60
    }
9707
60
  }
9708
78.8k
  return PostUpdate;
9709
78.8k
}
9710
9711
/// Called on a for stmt to check itself and nested loops (if any).
9712
/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9713
/// number of collapsed loops otherwise.
9714
static unsigned
9715
checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9716
                Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9717
                DSAStackTy &DSA,
9718
                Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9719
230k
                OMPLoopBasedDirective::HelperExprs &Built) {
9720
230k
  unsigned NestedLoopCount = 1;
9721
230k
  bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9722
230k
                                    
!isOpenMPLoopTransformationDirective(DKind)172k
;
9723
9724
230k
  if (CollapseLoopCountExpr) {
9725
    // Found 'collapse' clause - calculate collapse number.
9726
6.24k
    Expr::EvalResult Result;
9727
6.24k
    if (!CollapseLoopCountExpr->isValueDependent() &&
9728
6.24k
        
CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())4.93k
) {
9729
4.93k
      NestedLoopCount = Result.Val.getInt().getLimitedValue();
9730
4.93k
    } else {
9731
1.31k
      Built.clear(/*Size=*/1);
9732
1.31k
      return 1;
9733
1.31k
    }
9734
6.24k
  }
9735
229k
  unsigned OrderedLoopCount = 1;
9736
229k
  if (OrderedLoopCountExpr) {
9737
    // Found 'ordered' clause - calculate collapse number.
9738
568
    Expr::EvalResult EVResult;
9739
568
    if (!OrderedLoopCountExpr->isValueDependent() &&
9740
568
        OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9741
454
                                            SemaRef.getASTContext())) {
9742
454
      llvm::APSInt Result = EVResult.Val.getInt();
9743
454
      if (Result.getLimitedValue() < NestedLoopCount) {
9744
12
        SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9745
12
                     diag::err_omp_wrong_ordered_loop_count)
9746
12
            << OrderedLoopCountExpr->getSourceRange();
9747
12
        SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9748
12
                     diag::note_collapse_loop_count)
9749
12
            << CollapseLoopCountExpr->getSourceRange();
9750
12
      }
9751
454
      OrderedLoopCount = Result.getLimitedValue();
9752
454
    } else {
9753
114
      Built.clear(/*Size=*/1);
9754
114
      return 1;
9755
114
    }
9756
568
  }
9757
  // This is helper routine for loop directives (e.g., 'for', 'simd',
9758
  // 'for simd', etc.).
9759
229k
  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9760
229k
  unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9761
229k
  SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9762
229k
  if (!OMPLoopBasedDirective::doForAllLoops(
9763
229k
          AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9764
229k
          SupportsNonPerfectlyNested, NumLoops,
9765
229k
          [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9766
229k
           CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9767
233k
           &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9768
233k
            if (checkOpenMPIterationSpace(
9769
233k
                    DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9770
233k
                    NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9771
233k
                    VarsWithImplicitDSA, IterSpaces, Captures))
9772
8.50k
              return true;
9773
224k
            if (Cnt > 0 && 
Cnt >= NestedLoopCount2.57k
&&
9774
224k
                
IterSpaces[Cnt].CounterVar39
) {
9775
              // Handle initialization of captured loop iterator variables.
9776
26
              auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9777
26
              if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9778
6
                Captures[DRE] = DRE;
9779
6
              }
9780
26
            }
9781
224k
            return false;
9782
233k
          },
9783
229k
          [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9784
52
            Stmt *DependentPreInits = Transform->getPreInits();
9785
52
            if (!DependentPreInits)
9786
5
              return;
9787
145
            
for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup())47
{
9788
145
              auto *D = cast<VarDecl>(C);
9789
145
              DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9790
145
                                                  Transform->getBeginLoc());
9791
145
              Captures[Ref] = Ref;
9792
145
            }
9793
47
          }))
9794
8.50k
    return 0;
9795
9796
220k
  Built.clear(/* size */ NestedLoopCount);
9797
9798
220k
  if (SemaRef.CurContext->isDependentContext())
9799
58.9k
    return NestedLoopCount;
9800
9801
  // An example of what is generated for the following code:
9802
  //
9803
  //   #pragma omp simd collapse(2) ordered(2)
9804
  //   for (i = 0; i < NI; ++i)
9805
  //     for (k = 0; k < NK; ++k)
9806
  //       for (j = J0; j < NJ; j+=2) {
9807
  //         <loop body>
9808
  //       }
9809
  //
9810
  // We generate the code below.
9811
  // Note: the loop body may be outlined in CodeGen.
9812
  // Note: some counters may be C++ classes, operator- is used to find number of
9813
  // iterations and operator+= to calculate counter value.
9814
  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9815
  // or i64 is currently supported).
9816
  //
9817
  //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9818
  //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9819
  //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9820
  //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9821
  //     // similar updates for vars in clauses (e.g. 'linear')
9822
  //     <loop body (using local i and j)>
9823
  //   }
9824
  //   i = NI; // assign final values of counters
9825
  //   j = NJ;
9826
  //
9827
9828
  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9829
  // the iteration counts of the collapsed for loops.
9830
  // Precondition tests if there is at least one iteration (all conditions are
9831
  // true).
9832
161k
  auto PreCond = ExprResult(IterSpaces[0].PreCond);
9833
161k
  Expr *N0 = IterSpaces[0].NumIterations;
9834
161k
  ExprResult LastIteration32 =
9835
161k
      widenIterationCount(/*Bits=*/32,
9836
161k
                          SemaRef
9837
161k
                              .PerformImplicitConversion(
9838
161k
                                  N0->IgnoreImpCasts(), N0->getType(),
9839
161k
                                  Sema::AA_Converting, /*AllowExplicit=*/true)
9840
161k
                              .get(),
9841
161k
                          SemaRef);
9842
161k
  ExprResult LastIteration64 = widenIterationCount(
9843
161k
      /*Bits=*/64,
9844
161k
      SemaRef
9845
161k
          .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9846
161k
                                     Sema::AA_Converting,
9847
161k
                                     /*AllowExplicit=*/true)
9848
161k
          .get(),
9849
161k
      SemaRef);
9850
9851
161k
  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9852
0
    return NestedLoopCount;
9853
9854
161k
  ASTContext &C = SemaRef.Context;
9855
161k
  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9856
9857
161k
  Scope *CurScope = DSA.getCurScope();
9858
164k
  for (unsigned Cnt = 1; Cnt < NestedLoopCount; 
++Cnt2.25k
) {
9859
2.25k
    if (PreCond.isUsable()) {
9860
2.25k
      PreCond =
9861
2.25k
          SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9862
2.25k
                             PreCond.get(), IterSpaces[Cnt].PreCond);
9863
2.25k
    }
9864
2.25k
    Expr *N = IterSpaces[Cnt].NumIterations;
9865
2.25k
    SourceLocation Loc = N->getExprLoc();
9866
2.25k
    AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9867
2.25k
    if (LastIteration32.isUsable())
9868
2.25k
      LastIteration32 = SemaRef.BuildBinOp(
9869
2.25k
          CurScope, Loc, BO_Mul, LastIteration32.get(),
9870
2.25k
          SemaRef
9871
2.25k
              .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9872
2.25k
                                         Sema::AA_Converting,
9873
2.25k
                                         /*AllowExplicit=*/true)
9874
2.25k
              .get());
9875
2.25k
    if (LastIteration64.isUsable())
9876
2.25k
      LastIteration64 = SemaRef.BuildBinOp(
9877
2.25k
          CurScope, Loc, BO_Mul, LastIteration64.get(),
9878
2.25k
          SemaRef
9879
2.25k
              .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9880
2.25k
                                         Sema::AA_Converting,
9881
2.25k
                                         /*AllowExplicit=*/true)
9882
2.25k
              .get());
9883
2.25k
  }
9884
9885
  // Choose either the 32-bit or 64-bit version.
9886
161k
  ExprResult LastIteration = LastIteration64;
9887
161k
  if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9888
161k
      
(161k
LastIteration32.isUsable()161k
&&
9889
161k
       C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9890
161k
       
(160k
AllCountsNeedLessThan32Bits160k
||
NestedLoopCount == 1159k
||
9891
160k
        fitsInto(
9892
1.37k
            /*Bits=*/32,
9893
1.37k
            LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9894
1.37k
            LastIteration64.get(), SemaRef))))
9895
159k
    LastIteration = LastIteration32;
9896
161k
  QualType VType = LastIteration.get()->getType();
9897
161k
  QualType RealVType = VType;
9898
161k
  QualType StrideVType = VType;
9899
161k
  if (isOpenMPTaskLoopDirective(DKind)) {
9900
41.4k
    VType =
9901
41.4k
        SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9902
41.4k
    StrideVType =
9903
41.4k
        SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9904
41.4k
  }
9905
9906
161k
  if (!LastIteration.isUsable())
9907
0
    return 0;
9908
9909
  // Save the number of iterations.
9910
161k
  ExprResult NumIterations = LastIteration;
9911
161k
  {
9912
161k
    LastIteration = SemaRef.BuildBinOp(
9913
161k
        CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9914
161k
        LastIteration.get(),
9915
161k
        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9916
161k
    if (!LastIteration.isUsable())
9917
0
      return 0;
9918
161k
  }
9919
9920
  // Calculate the last iteration number beforehand instead of doing this on
9921
  // each iteration. Do not do this if the number of iterations may be kfold-ed.
9922
161k
  bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9923
161k
  ExprResult CalcLastIteration;
9924
161k
  if (!IsConstant) {
9925
33.9k
    ExprResult SaveRef =
9926
33.9k
        tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9927
33.9k
    LastIteration = SaveRef;
9928
9929
    // Prepare SaveRef + 1.
9930
33.9k
    NumIterations = SemaRef.BuildBinOp(
9931
33.9k
        CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9932
33.9k
        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9933
33.9k
    if (!NumIterations.isUsable())
9934
0
      return 0;
9935
33.9k
  }
9936
9937
161k
  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9938
9939
  // Build variables passed into runtime, necessary for worksharing directives.
9940
161k
  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9941
161k
  if (isOpenMPWorksharingDirective(DKind) || 
isOpenMPTaskLoopDirective(DKind)85.7k
||
9942
161k
      
isOpenMPDistributeDirective(DKind)44.2k
||
9943
161k
      
isOpenMPGenericLoopDirective(DKind)14.4k
||
9944
161k
      
isOpenMPLoopTransformationDirective(DKind)14.4k
) {
9945
    // Lower bound variable, initialized with zero.
9946
147k
    VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9947
147k
    LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9948
147k
    SemaRef.AddInitializerToDecl(LBDecl,
9949
147k
                                 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9950
147k
                                 /*DirectInit*/ false);
9951
9952
    // Upper bound variable, initialized with last iteration number.
9953
147k
    VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9954
147k
    UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9955
147k
    SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9956
147k
                                 /*DirectInit*/ false);
9957
9958
    // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9959
    // This will be used to implement clause 'lastprivate'.
9960
147k
    QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9961
147k
    VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9962
147k
    IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9963
147k
    SemaRef.AddInitializerToDecl(ILDecl,
9964
147k
                                 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9965
147k
                                 /*DirectInit*/ false);
9966
9967
    // Stride variable returned by runtime (we initialize it to 1 by default).
9968
147k
    VarDecl *STDecl =
9969
147k
        buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9970
147k
    ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9971
147k
    SemaRef.AddInitializerToDecl(STDecl,
9972
147k
                                 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9973
147k
                                 /*DirectInit*/ false);
9974
9975
    // Build expression: UB = min(UB, LastIteration)
9976
    // It is necessary for CodeGen of directives with static scheduling.
9977
147k
    ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9978
147k
                                                UB.get(), LastIteration.get());
9979
147k
    ExprResult CondOp = SemaRef.ActOnConditionalOp(
9980
147k
        LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9981
147k
        LastIteration.get(), UB.get());
9982
147k
    EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9983
147k
                             CondOp.get());
9984
147k
    EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9985
9986
    // If we have a combined directive that combines 'distribute', 'for' or
9987
    // 'simd' we need to be able to access the bounds of the schedule of the
9988
    // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9989
    // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9990
147k
    if (isOpenMPLoopBoundSharingDirective(DKind)) {
9991
      // Lower bound variable, initialized with zero.
9992
35.8k
      VarDecl *CombLBDecl =
9993
35.8k
          buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9994
35.8k
      CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9995
35.8k
      SemaRef.AddInitializerToDecl(
9996
35.8k
          CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9997
35.8k
          /*DirectInit*/ false);
9998
9999
      // Upper bound variable, initialized with last iteration number.
10000
35.8k
      VarDecl *CombUBDecl =
10001
35.8k
          buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
10002
35.8k
      CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
10003
35.8k
      SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
10004
35.8k
                                   /*DirectInit*/ false);
10005
10006
35.8k
      ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
10007
35.8k
          CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
10008
35.8k
      ExprResult CombCondOp =
10009
35.8k
          SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
10010
35.8k
                                     LastIteration.get(), CombUB.get());
10011
35.8k
      CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
10012
35.8k
                                   CombCondOp.get());
10013
35.8k
      CombEUB =
10014
35.8k
          SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
10015
10016
35.8k
      const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
10017
      // We expect to have at least 2 more parameters than the 'parallel'
10018
      // directive does - the lower and upper bounds of the previous schedule.
10019
35.8k
      assert(CD->getNumParams() >= 4 &&
10020
35.8k
             "Unexpected number of parameters in loop combined directive");
10021
10022
      // Set the proper type for the bounds given what we learned from the
10023
      // enclosed loops.
10024
35.8k
      ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
10025
35.8k
      ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
10026
10027
      // Previous lower and upper bounds are obtained from the region
10028
      // parameters.
10029
35.8k
      PrevLB =
10030
35.8k
          buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
10031
35.8k
      PrevUB =
10032
35.8k
          buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
10033
35.8k
    }
10034
147k
  }
10035
10036
  // Build the iteration variable and its initialization before loop.
10037
161k
  ExprResult IV;
10038
161k
  ExprResult Init, CombInit;
10039
161k
  {
10040
161k
    VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
10041
161k
    IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
10042
161k
    Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
10043
161k
                 
isOpenMPGenericLoopDirective(DKind)85.7k
||
10044
161k
                 
isOpenMPTaskLoopDirective(DKind)85.7k
||
10045
161k
                 
isOpenMPDistributeDirective(DKind)44.2k
||
10046
161k
                 
isOpenMPLoopTransformationDirective(DKind)14.4k
)
10047
161k
                    ? 
LB.get()147k
10048
161k
                    : 
SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get()14.2k
;
10049
161k
    Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
10050
161k
    Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
10051
10052
161k
    if (isOpenMPLoopBoundSharingDirective(DKind)) {
10053
35.8k
      Expr *CombRHS =
10054
35.8k
          (isOpenMPWorksharingDirective(DKind) ||
10055
35.8k
           
isOpenMPGenericLoopDirective(DKind)0
||
10056
35.8k
           
isOpenMPTaskLoopDirective(DKind)0
||
10057
35.8k
           
isOpenMPDistributeDirective(DKind)0
)
10058
35.8k
              ? CombLB.get()
10059
35.8k
              : 
SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get()0
;
10060
35.8k
      CombInit =
10061
35.8k
          SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
10062
35.8k
      CombInit =
10063
35.8k
          SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
10064
35.8k
    }
10065
161k
  }
10066
10067
161k
  bool UseStrictCompare =
10068
161k
      RealVType->hasUnsignedIntegerRepresentation() &&
10069
161k
      
llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) 1.39k
{
10070
1.46k
        return LIS.IsStrictCompare;
10071
1.46k
      });
10072
  // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
10073
  // unsigned IV)) for worksharing loops.
10074
161k
  SourceLocation CondLoc = AStmt->getBeginLoc();
10075
161k
  Expr *BoundUB = UB.get();
10076
161k
  if (UseStrictCompare) {
10077
940
    BoundUB =
10078
940
        SemaRef
10079
940
            .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
10080
940
                        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10081
940
            .get();
10082
940
    BoundUB =
10083
940
        SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
10084
940
  }
10085
161k
  ExprResult Cond =
10086
161k
      (isOpenMPWorksharingDirective(DKind) ||
10087
161k
       
isOpenMPGenericLoopDirective(DKind)85.7k
||
10088
161k
       
isOpenMPTaskLoopDirective(DKind)85.7k
||
isOpenMPDistributeDirective(DKind)44.2k
||
10089
161k
       
isOpenMPLoopTransformationDirective(DKind)14.4k
)
10090
161k
          ? SemaRef.BuildBinOp(CurScope, CondLoc,
10091
147k
                               UseStrictCompare ? 
BO_LT836
:
BO_LE146k
, IV.get(),
10092
147k
                               BoundUB)
10093
161k
          : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10094
14.2k
                               NumIterations.get());
10095
161k
  ExprResult CombDistCond;
10096
161k
  if (isOpenMPLoopBoundSharingDirective(DKind)) {
10097
35.8k
    CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10098
35.8k
                                      NumIterations.get());
10099
35.8k
  }
10100
10101
161k
  ExprResult CombCond;
10102
161k
  if (isOpenMPLoopBoundSharingDirective(DKind)) {
10103
35.8k
    Expr *BoundCombUB = CombUB.get();
10104
35.8k
    if (UseStrictCompare) {
10105
83
      BoundCombUB =
10106
83
          SemaRef
10107
83
              .BuildBinOp(
10108
83
                  CurScope, CondLoc, BO_Add, BoundCombUB,
10109
83
                  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10110
83
              .get();
10111
83
      BoundCombUB =
10112
83
          SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
10113
83
              .get();
10114
83
    }
10115
35.8k
    CombCond =
10116
35.8k
        SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? 
BO_LT83
:
BO_LE35.7k
,
10117
35.8k
                           IV.get(), BoundCombUB);
10118
35.8k
  }
10119
  // Loop increment (IV = IV + 1)
10120
161k
  SourceLocation IncLoc = AStmt->getBeginLoc();
10121
161k
  ExprResult Inc =
10122
161k
      SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
10123
161k
                         SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
10124
161k
  if (!Inc.isUsable())
10125
0
    return 0;
10126
161k
  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
10127
161k
  Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
10128
161k
  if (!Inc.isUsable())
10129
0
    return 0;
10130
10131
  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
10132
  // Used for directives with static scheduling.
10133
  // In combined construct, add combined version that use CombLB and CombUB
10134
  // base variables for the update
10135
161k
  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
10136
161k
  if (isOpenMPWorksharingDirective(DKind) || 
isOpenMPTaskLoopDirective(DKind)85.7k
||
10137
161k
      
isOpenMPGenericLoopDirective(DKind)44.2k
||
10138
161k
      
isOpenMPDistributeDirective(DKind)44.2k
||
10139
161k
      
isOpenMPLoopTransformationDirective(DKind)14.4k
) {
10140
    // LB + ST
10141
147k
    NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
10142
147k
    if (!NextLB.isUsable())
10143
0
      return 0;
10144
    // LB = LB + ST
10145
147k
    NextLB =
10146
147k
        SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
10147
147k
    NextLB =
10148
147k
        SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
10149
147k
    if (!NextLB.isUsable())
10150
0
      return 0;
10151
    // UB + ST
10152
147k
    NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
10153
147k
    if (!NextUB.isUsable())
10154
0
      return 0;
10155
    // UB = UB + ST
10156
147k
    NextUB =
10157
147k
        SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
10158
147k
    NextUB =
10159
147k
        SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
10160
147k
    if (!NextUB.isUsable())
10161
0
      return 0;
10162
147k
    if (isOpenMPLoopBoundSharingDirective(DKind)) {
10163
35.8k
      CombNextLB =
10164
35.8k
          SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
10165
35.8k
      if (!NextLB.isUsable())
10166
0
        return 0;
10167
      // LB = LB + ST
10168
35.8k
      CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
10169
35.8k
                                      CombNextLB.get());
10170
35.8k
      CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
10171
35.8k
                                               /*DiscardedValue*/ false);
10172
35.8k
      if (!CombNextLB.isUsable())
10173
0
        return 0;
10174
      // UB + ST
10175
35.8k
      CombNextUB =
10176
35.8k
          SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
10177
35.8k
      if (!CombNextUB.isUsable())
10178
0
        return 0;
10179
      // UB = UB + ST
10180
35.8k
      CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
10181
35.8k
                                      CombNextUB.get());
10182
35.8k
      CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
10183
35.8k
                                               /*DiscardedValue*/ false);
10184
35.8k
      if (!CombNextUB.isUsable())
10185
0
        return 0;
10186
35.8k
    }
10187
147k
  }
10188
10189
  // Create increment expression for distribute loop when combined in a same
10190
  // directive with for as IV = IV + ST; ensure upper bound expression based
10191
  // on PrevUB instead of NumIterations - used to implement 'for' when found
10192
  // in combination with 'distribute', like in 'distribute parallel for'
10193
161k
  SourceLocation DistIncLoc = AStmt->getBeginLoc();
10194
161k
  ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10195
161k
  if (isOpenMPLoopBoundSharingDirective(DKind)) {
10196
35.8k
    DistCond = SemaRef.BuildBinOp(
10197
35.8k
        CurScope, CondLoc, UseStrictCompare ? 
BO_LT83
:
BO_LE35.7k
, IV.get(), BoundUB);
10198
35.8k
    assert(DistCond.isUsable() && "distribute cond expr was not built");
10199
10200
35.8k
    DistInc =
10201
35.8k
        SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
10202
35.8k
    assert(DistInc.isUsable() && "distribute inc expr was not built");
10203
35.8k
    DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
10204
35.8k
                                 DistInc.get());
10205
35.8k
    DistInc =
10206
35.8k
        SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
10207
35.8k
    assert(DistInc.isUsable() && "distribute inc expr was not built");
10208
10209
    // Build expression: UB = min(UB, prevUB) for #for in composite or combined
10210
    // construct
10211
35.8k
    ExprResult NewPrevUB = PrevUB;
10212
35.8k
    SourceLocation DistEUBLoc = AStmt->getBeginLoc();
10213
35.8k
    if (!SemaRef.Context.hasSameType(UB.get()->getType(),
10214
35.8k
                                     PrevUB.get()->getType())) {
10215
35.8k
      NewPrevUB = SemaRef.BuildCStyleCastExpr(
10216
35.8k
          DistEUBLoc,
10217
35.8k
          SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
10218
35.8k
          DistEUBLoc, NewPrevUB.get());
10219
35.8k
      if (!NewPrevUB.isUsable())
10220
0
        return 0;
10221
35.8k
    }
10222
35.8k
    ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
10223
35.8k
                                                UB.get(), NewPrevUB.get());
10224
35.8k
    ExprResult CondOp = SemaRef.ActOnConditionalOp(
10225
35.8k
        DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
10226
35.8k
    PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
10227
35.8k
                                 CondOp.get());
10228
35.8k
    PrevEUB =
10229
35.8k
        SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
10230
10231
    // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
10232
    // parallel for is in combination with a distribute directive with
10233
    // schedule(static, 1)
10234
35.8k
    Expr *BoundPrevUB = PrevUB.get();
10235
35.8k
    if (UseStrictCompare) {
10236
83
      BoundPrevUB =
10237
83
          SemaRef
10238
83
              .BuildBinOp(
10239
83
                  CurScope, CondLoc, BO_Add, BoundPrevUB,
10240
83
                  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10241
83
              .get();
10242
83
      BoundPrevUB =
10243
83
          SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
10244
83
              .get();
10245
83
    }
10246
35.8k
    ParForInDistCond =
10247
35.8k
        SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? 
BO_LT83
:
BO_LE35.7k
,
10248
35.8k
                           IV.get(), BoundPrevUB);
10249
35.8k
  }
10250
10251
  // Build updates and final values of the loop counters.
10252
161k
  bool HasErrors = false;
10253
161k
  Built.Counters.resize(NestedLoopCount);
10254
161k
  Built.Inits.resize(NestedLoopCount);
10255
161k
  Built.Updates.resize(NestedLoopCount);
10256
161k
  Built.Finals.resize(NestedLoopCount);
10257
161k
  Built.DependentCounters.resize(NestedLoopCount);
10258
161k
  Built.DependentInits.resize(NestedLoopCount);
10259
161k
  Built.FinalsConditions.resize(NestedLoopCount);
10260
161k
  {
10261
    // We implement the following algorithm for obtaining the
10262
    // original loop iteration variable values based on the
10263
    // value of the collapsed loop iteration variable IV.
10264
    //
10265
    // Let n+1 be the number of collapsed loops in the nest.
10266
    // Iteration variables (I0, I1, .... In)
10267
    // Iteration counts (N0, N1, ... Nn)
10268
    //
10269
    // Acc = IV;
10270
    //
10271
    // To compute Ik for loop k, 0 <= k <= n, generate:
10272
    //    Prod = N(k+1) * N(k+2) * ... * Nn;
10273
    //    Ik = Acc / Prod;
10274
    //    Acc -= Ik * Prod;
10275
    //
10276
161k
    ExprResult Acc = IV;
10277
325k
    for (unsigned int Cnt = 0; Cnt < NestedLoopCount; 
++Cnt163k
) {
10278
164k
      LoopIterationSpace &IS = IterSpaces[Cnt];
10279
164k
      SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
10280
164k
      ExprResult Iter;
10281
10282
      // Compute prod
10283
164k
      ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10284
167k
      for (unsigned int K = Cnt + 1; K < NestedLoopCount; 
++K3.66k
)
10285
3.66k
        Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
10286
3.66k
                                  IterSpaces[K].NumIterations);
10287
10288
      // Iter = Acc / Prod
10289
      // If there is at least one more inner loop to avoid
10290
      // multiplication by 1.
10291
164k
      if (Cnt + 1 < NestedLoopCount)
10292
2.25k
        Iter =
10293
2.25k
            SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
10294
161k
      else
10295
161k
        Iter = Acc;
10296
164k
      if (!Iter.isUsable()) {
10297
0
        HasErrors = true;
10298
0
        break;
10299
0
      }
10300
10301
      // Update Acc:
10302
      // Acc -= Iter * Prod
10303
      // Check if there is at least one more inner loop to avoid
10304
      // multiplication by 1.
10305
164k
      if (Cnt + 1 < NestedLoopCount)
10306
2.25k
        Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
10307
2.25k
                                  Prod.get());
10308
161k
      else
10309
161k
        Prod = Iter;
10310
164k
      Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
10311
10312
      // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10313
164k
      auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10314
164k
      DeclRefExpr *CounterVar = buildDeclRefExpr(
10315
164k
          SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
10316
164k
          /*RefersToCapture=*/true);
10317
164k
      ExprResult Init =
10318
164k
          buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
10319
164k
                           IS.CounterInit, IS.IsNonRectangularLB, Captures);
10320
164k
      if (!Init.isUsable()) {
10321
0
        HasErrors = true;
10322
0
        break;
10323
0
      }
10324
164k
      ExprResult Update = buildCounterUpdate(
10325
164k
          SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10326
164k
          IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10327
164k
      if (!Update.isUsable()) {
10328
220
        HasErrors = true;
10329
220
        break;
10330
220
      }
10331
10332
      // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10333
163k
      ExprResult Final =
10334
163k
          buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
10335
163k
                             IS.CounterInit, IS.NumIterations, IS.CounterStep,
10336
163k
                             IS.Subtract, IS.IsNonRectangularLB, &Captures);
10337
163k
      if (!Final.isUsable()) {
10338
0
        HasErrors = true;
10339
0
        break;
10340
0
      }
10341
10342
163k
      if (!Update.isUsable() || !Final.isUsable()) {
10343
0
        HasErrors = true;
10344
0
        break;
10345
0
      }
10346
      // Save results
10347
163k
      Built.Counters[Cnt] = IS.CounterVar;
10348
163k
      Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10349
163k
      Built.Inits[Cnt] = Init.get();
10350
163k
      Built.Updates[Cnt] = Update.get();
10351
163k
      Built.Finals[Cnt] = Final.get();
10352
163k
      Built.DependentCounters[Cnt] = nullptr;
10353
163k
      Built.DependentInits[Cnt] = nullptr;
10354
163k
      Built.FinalsConditions[Cnt] = nullptr;
10355
163k
      if (IS.IsNonRectangularLB || 
IS.IsNonRectangularUB163k
) {
10356
91
        Built.DependentCounters[Cnt] = Built.Counters[IS.LoopDependentIdx - 1];
10357
91
        Built.DependentInits[Cnt] = Built.Inits[IS.LoopDependentIdx - 1];
10358
91
        Built.FinalsConditions[Cnt] = IS.FinalCondition;
10359
91
      }
10360
163k
    }
10361
161k
  }
10362
10363
161k
  if (HasErrors)
10364
220
    return 0;
10365
10366
  // Save results
10367
161k
  Built.IterationVarRef = IV.get();
10368
161k
  Built.LastIteration = LastIteration.get();
10369
161k
  Built.NumIterations = NumIterations.get();
10370
161k
  Built.CalcLastIteration = SemaRef
10371
161k
                                .ActOnFinishFullExpr(CalcLastIteration.get(),
10372
161k
                                                     /*DiscardedValue=*/false)
10373
161k
                                .get();
10374
161k
  Built.PreCond = PreCond.get();
10375
161k
  Built.PreInits = buildPreInits(C, Captures);
10376
161k
  Built.Cond = Cond.get();
10377
161k
  Built.Init = Init.get();
10378
161k
  Built.Inc = Inc.get();
10379
161k
  Built.LB = LB.get();
10380
161k
  Built.UB = UB.get();
10381
161k
  Built.IL = IL.get();
10382
161k
  Built.ST = ST.get();
10383
161k
  Built.EUB = EUB.get();
10384
161k
  Built.NLB = NextLB.get();
10385
161k
  Built.NUB = NextUB.get();
10386
161k
  Built.PrevLB = PrevLB.get();
10387
161k
  Built.PrevUB = PrevUB.get();
10388
161k
  Built.DistInc = DistInc.get();
10389
161k
  Built.PrevEUB = PrevEUB.get();
10390
161k
  Built.DistCombinedFields.LB = CombLB.get();
10391
161k
  Built.DistCombinedFields.UB = CombUB.get();
10392
161k
  Built.DistCombinedFields.EUB = CombEUB.get();
10393
161k
  Built.DistCombinedFields.Init = CombInit.get();
10394
161k
  Built.DistCombinedFields.Cond = CombCond.get();
10395
161k
  Built.DistCombinedFields.NLB = CombNextLB.get();
10396
161k
  Built.DistCombinedFields.NUB = CombNextUB.get();
10397
161k
  Built.DistCombinedFields.DistCond = CombDistCond.get();
10398
161k
  Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
10399
10400
161k
  return NestedLoopCount;
10401
161k
}
10402
10403
230k
static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
10404
230k
  auto CollapseClauses =
10405
230k
      OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10406
230k
  if (CollapseClauses.begin() != CollapseClauses.end())
10407
6.24k
    return (*CollapseClauses.begin())->getNumForLoops();
10408
224k
  return nullptr;
10409
230k
}
10410
10411
75.8k
static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
10412
75.8k
  auto OrderedClauses =
10413
75.8k
      OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10414
75.8k
  if (OrderedClauses.begin() != OrderedClauses.end())
10415
1.23k
    return (*OrderedClauses.begin())->getNumForLoops();
10416
74.5k
  return nullptr;
10417
75.8k
}
10418
10419
static bool checkSimdlenSafelenSpecified(Sema &S,
10420
126k
                                         const ArrayRef<OMPClause *> Clauses) {
10421
126k
  const OMPSafelenClause *Safelen = nullptr;
10422
126k
  const OMPSimdlenClause *Simdlen = nullptr;
10423
10424
126k
  for (const OMPClause *Clause : Clauses) {
10425
94.1k
    if (Clause->getClauseKind() == OMPC_safelen)
10426
3.72k
      Safelen = cast<OMPSafelenClause>(Clause);
10427
90.3k
    else if (Clause->getClauseKind() == OMPC_simdlen)
10428
2.57k
      Simdlen = cast<OMPSimdlenClause>(Clause);
10429
94.1k
    if (Safelen && 
Simdlen6.06k
)
10430
603
      break;
10431
94.1k
  }
10432
10433
126k
  if (Simdlen && 
Safelen2.57k
) {
10434
603
    const Expr *SimdlenLength = Simdlen->getSimdlen();
10435
603
    const Expr *SafelenLength = Safelen->getSafelen();
10436
603
    if (SimdlenLength->isValueDependent() || 
SimdlenLength->isTypeDependent()515
||
10437
603
        
SimdlenLength->isInstantiationDependent()515
||
10438
603
        
SimdlenLength->containsUnexpandedParameterPack()515
)
10439
88
      return false;
10440
515
    if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
10441
515
        SafelenLength->isInstantiationDependent() ||
10442
515
        SafelenLength->containsUnexpandedParameterPack())
10443
0
      return false;
10444
515
    Expr::EvalResult SimdlenResult, SafelenResult;
10445
515
    SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
10446
515
    SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
10447
515
    llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
10448
515
    llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
10449
    // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10450
    // If both simdlen and safelen clauses are specified, the value of the
10451
    // simdlen parameter must be less than or equal to the value of the safelen
10452
    // parameter.
10453
515
    if (SimdlenRes > SafelenRes) {
10454
120
      S.Diag(SimdlenLength->getExprLoc(),
10455
120
             diag::err_omp_wrong_simdlen_safelen_values)
10456
120
          << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
10457
120
      return true;
10458
120
    }
10459
515
  }
10460
126k
  return false;
10461
126k
}
10462
10463
static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10464
                                        OpenMPDirectiveKind K,
10465
                                        DSAStackTy *Stack);
10466
10467
21.6k
bool Sema::checkLastPrivateForMappedDirectives(ArrayRef<OMPClause *> Clauses) {
10468
10469
  // Check for syntax of lastprivate
10470
  // Param of the lastprivate have different meanings in the mapped directives
10471
  // e.g. "omp loop" Only loop iteration vars are allowed in lastprivate clause
10472
  //      "omp for"  lastprivate vars must be shared
10473
21.6k
  if (getLangOpts().OpenMP >= 50 &&
10474
21.6k
      
DSAStack15.4k
->getMappedDirective() == OMPD_loop15.4k
&&
10475
21.6k
      
checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, 97
DSAStack97
)) {
10476
3
    return false;
10477
3
  }
10478
21.5k
  return true;
10479
21.6k
}
10480
10481
StmtResult
10482
Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10483
                               SourceLocation StartLoc, SourceLocation EndLoc,
10484
8.98k
                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10485
8.98k
  if (!AStmt)
10486
24
    return StmtError();
10487
10488
8.96k
  if (!checkLastPrivateForMappedDirectives(Clauses))
10489
3
    return StmtError();
10490
10491
8.96k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10492
8.96k
  OMPLoopBasedDirective::HelperExprs B;
10493
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10494
  // define the nested loops number.
10495
8.96k
  unsigned NestedLoopCount = checkOpenMPLoop(
10496
8.96k
      OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10497
8.96k
      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10498
8.96k
  if (NestedLoopCount == 0)
10499
413
    return StmtError();
10500
10501
8.54k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10502
8.54k
         "omp simd loop exprs were not built");
10503
10504
8.54k
  if (!CurContext->isDependentContext()) {
10505
    // Finalize the clauses that need pre-built expressions for CodeGen.
10506
6.30k
    for (OMPClause *C : Clauses) {
10507
2.60k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
10508
421
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10509
421
                                     B.NumIterations, *this, CurScope,
10510
421
                                     DSAStack))
10511
0
          return StmtError();
10512
2.60k
    }
10513
6.30k
  }
10514
10515
8.54k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
10516
12
    return StmtError();
10517
10518
8.53k
  setFunctionHasBranchProtectedScope();
10519
8.53k
  auto *SimdDirective = OMPSimdDirective::Create(
10520
8.53k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10521
8.53k
      DSAStack->getMappedDirective());
10522
8.53k
  return SimdDirective;
10523
8.54k
}
10524
10525
StmtResult
10526
Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10527
                              SourceLocation StartLoc, SourceLocation EndLoc,
10528
10.5k
                              VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10529
10.5k
  if (!AStmt)
10530
50
    return StmtError();
10531
10532
10.5k
  if (!checkLastPrivateForMappedDirectives(Clauses))
10533
0
    return StmtError();
10534
10535
10.5k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10536
10.5k
  OMPLoopBasedDirective::HelperExprs B;
10537
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10538
  // define the nested loops number.
10539
10.5k
  unsigned NestedLoopCount = checkOpenMPLoop(
10540
10.5k
      OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10541
10.5k
      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10542
10.5k
  if (NestedLoopCount == 0)
10543
439
    return StmtError();
10544
10545
10.0k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10546
10.0k
         "omp for loop exprs were not built");
10547
10548
10.0k
  if (!CurContext->isDependentContext()) {
10549
    // Finalize the clauses that need pre-built expressions for CodeGen.
10550
7.27k
    for (OMPClause *C : Clauses) {
10551
4.22k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
10552
253
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10553
253
                                     B.NumIterations, *this, CurScope,
10554
253
                                     DSAStack))
10555
0
          return StmtError();
10556
4.22k
    }
10557
7.27k
  }
10558
10559
10.0k
  auto *ForDirective = OMPForDirective::Create(
10560
10.0k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10561
10.0k
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion(),
10562
10.0k
      DSAStack->getMappedDirective());
10563
10.0k
  return ForDirective;
10564
10.0k
}
10565
10566
StmtResult Sema::ActOnOpenMPForSimdDirective(
10567
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10568
8.02k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10569
8.02k
  if (!AStmt)
10570
12
    return StmtError();
10571
10572
8.01k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10573
8.01k
  OMPLoopBasedDirective::HelperExprs B;
10574
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10575
  // define the nested loops number.
10576
8.01k
  unsigned NestedLoopCount =
10577
8.01k
      checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10578
8.01k
                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10579
8.01k
                      VarsWithImplicitDSA, B);
10580
8.01k
  if (NestedLoopCount == 0)
10581
324
    return StmtError();
10582
10583
7.69k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10584
7.69k
         "omp for simd loop exprs were not built");
10585
10586
7.69k
  if (!CurContext->isDependentContext()) {
10587
    // Finalize the clauses that need pre-built expressions for CodeGen.
10588
5.63k
    for (OMPClause *C : Clauses) {
10589
2.24k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
10590
255
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10591
255
                                     B.NumIterations, *this, CurScope,
10592
255
                                     DSAStack))
10593
0
          return StmtError();
10594
2.24k
    }
10595
5.63k
  }
10596
10597
7.69k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
10598
12
    return StmtError();
10599
10600
7.67k
  setFunctionHasBranchProtectedScope();
10601
7.67k
  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10602
7.67k
                                     Clauses, AStmt, B);
10603
7.69k
}
10604
10605
StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10606
                                              Stmt *AStmt,
10607
                                              SourceLocation StartLoc,
10608
6.04k
                                              SourceLocation EndLoc) {
10609
6.04k
  if (!AStmt)
10610
0
    return StmtError();
10611
10612
6.04k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10613
6.04k
  auto BaseStmt = AStmt;
10614
12.0k
  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10615
6.04k
    BaseStmt = CS->getCapturedStmt();
10616
6.04k
  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10617
6.04k
    auto S = C->children();
10618
6.04k
    if (S.begin() == S.end())
10619
428
      return StmtError();
10620
    // All associated statements must be '#pragma omp section' except for
10621
    // the first one.
10622
5.61k
    for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10623
133
      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10624
11
        if (SectionStmt)
10625
11
          Diag(SectionStmt->getBeginLoc(),
10626
11
               diag::err_omp_sections_substmt_not_section);
10627
11
        return StmtError();
10628
11
      }
10629
122
      cast<OMPSectionDirective>(SectionStmt)
10630
122
          ->setHasCancel(DSAStack->isCancelRegion());
10631
122
    }
10632
5.61k
  } else {
10633
2
    Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10634
2
    return StmtError();
10635
2
  }
10636
10637
5.60k
  setFunctionHasBranchProtectedScope();
10638
10639
5.60k
  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10640
5.60k
                                      DSAStack->getTaskgroupReductionRef(),
10641
5.60k
                                      DSAStack->isCancelRegion());
10642
6.04k
}
10643
10644
StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
10645
                                             SourceLocation StartLoc,
10646
1.39k
                                             SourceLocation EndLoc) {
10647
1.39k
  if (!AStmt)
10648
153
    return StmtError();
10649
10650
1.23k
  setFunctionHasBranchProtectedScope();
10651
1.23k
  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10652
10653
1.23k
  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10654
1.23k
                                     DSAStack->isCancelRegion());
10655
1.39k
}
10656
10657
154
static Expr *getDirectCallExpr(Expr *E) {
10658
154
  E = E->IgnoreParenCasts()->IgnoreImplicit();
10659
154
  if (auto *CE = dyn_cast<CallExpr>(E))
10660
133
    if (CE->getDirectCallee())
10661
125
      return E;
10662
29
  return nullptr;
10663
154
}
10664
10665
StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10666
                                              Stmt *AStmt,
10667
                                              SourceLocation StartLoc,
10668
150
                                              SourceLocation EndLoc) {
10669
150
  if (!AStmt)
10670
2
    return StmtError();
10671
10672
148
  Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10673
10674
  // 5.1 OpenMP
10675
  // expression-stmt : an expression statement with one of the following forms:
10676
  //   expression = target-call ( [expression-list] );
10677
  //   target-call ( [expression-list] );
10678
10679
148
  SourceLocation TargetCallLoc;
10680
10681
148
  if (!CurContext->isDependentContext()) {
10682
143
    Expr *TargetCall = nullptr;
10683
10684
143
    auto *E = dyn_cast<Expr>(S);
10685
143
    if (!E) {
10686
2
      Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10687
2
      return StmtError();
10688
2
    }
10689
10690
141
    E = E->IgnoreParenCasts()->IgnoreImplicit();
10691
10692
141
    if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10693
32
      if (BO->getOpcode() == BO_Assign)
10694
30
        TargetCall = getDirectCallExpr(BO->getRHS());
10695
109
    } else {
10696
109
      if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10697
20
        if (COCE->getOperator() == OO_Equal)
10698
20
          TargetCall = getDirectCallExpr(COCE->getArg(1));
10699
109
      if (!TargetCall)
10700
104
        TargetCall = getDirectCallExpr(E);
10701
109
    }
10702
141
    if (!TargetCall) {
10703
16
      Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10704
16
      return StmtError();
10705
16
    }
10706
125
    TargetCallLoc = TargetCall->getExprLoc();
10707
125
  }
10708
10709
130
  setFunctionHasBranchProtectedScope();
10710
10711
130
  return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10712
130
                                      TargetCallLoc);
10713
148
}
10714
10715
static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10716
                                        OpenMPDirectiveKind K,
10717
1.75k
                                        DSAStackTy *Stack) {
10718
1.75k
  bool ErrorFound = false;
10719
2.57k
  for (OMPClause *C : Clauses) {
10720
2.57k
    if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10721
78
      for (Expr *RefExpr : LPC->varlists()) {
10722
78
        SourceLocation ELoc;
10723
78
        SourceRange ERange;
10724
78
        Expr *SimpleRefExpr = RefExpr;
10725
78
        auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10726
78
        if (ValueDecl *D = Res.first) {
10727
57
          auto &&Info = Stack->isLoopControlVariable(D);
10728
57
          if (!Info.first) {
10729
15
            S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10730
15
                << getOpenMPDirectiveName(K);
10731
15
            ErrorFound = true;
10732
15
          }
10733
57
        }
10734
78
      }
10735
78
    }
10736
2.57k
  }
10737
1.75k
  return ErrorFound;
10738
1.75k
}
10739
10740
StmtResult Sema::ActOnOpenMPGenericLoopDirective(
10741
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10742
0
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10743
0
  if (!AStmt)
10744
0
    return StmtError();
10745
10746
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10747
  // A list item may not appear in a lastprivate clause unless it is the
10748
  // loop iteration variable of a loop that is associated with the construct.
10749
0
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack))
10750
0
    return StmtError();
10751
10752
0
  auto *CS = cast<CapturedStmt>(AStmt);
10753
  // 1.2.2 OpenMP Language Terminology
10754
  // Structured block - An executable statement with a single entry at the
10755
  // top and a single exit at the bottom.
10756
  // The point of exit cannot be a branch out of the structured block.
10757
  // longjmp() and throw() must not violate the entry/exit criteria.
10758
0
  CS->getCapturedDecl()->setNothrow();
10759
10760
0
  OMPLoopDirective::HelperExprs B;
10761
  // In presence of clause 'collapse', it will define the nested loops number.
10762
0
  unsigned NestedLoopCount = checkOpenMPLoop(
10763
0
      OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10764
0
      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10765
0
  if (NestedLoopCount == 0)
10766
0
    return StmtError();
10767
10768
0
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10769
0
         "omp loop exprs were not built");
10770
10771
0
  setFunctionHasBranchProtectedScope();
10772
0
  return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10773
0
                                         NestedLoopCount, Clauses, AStmt, B);
10774
0
}
10775
10776
StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective(
10777
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10778
211
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10779
211
  if (!AStmt)
10780
0
    return StmtError();
10781
10782
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10783
  // A list item may not appear in a lastprivate clause unless it is the
10784
  // loop iteration variable of a loop that is associated with the construct.
10785
211
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack))
10786
3
    return StmtError();
10787
10788
208
  auto *CS = cast<CapturedStmt>(AStmt);
10789
  // 1.2.2 OpenMP Language Terminology
10790
  // Structured block - An executable statement with a single entry at the
10791
  // top and a single exit at the bottom.
10792
  // The point of exit cannot be a branch out of the structured block.
10793
  // longjmp() and throw() must not violate the entry/exit criteria.
10794
208
  CS->getCapturedDecl()->setNothrow();
10795
208
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10796
416
       ThisCaptureLevel > 1; 
--ThisCaptureLevel208
) {
10797
208
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
10798
    // 1.2.2 OpenMP Language Terminology
10799
    // Structured block - An executable statement with a single entry at the
10800
    // top and a single exit at the bottom.
10801
    // The point of exit cannot be a branch out of the structured block.
10802
    // longjmp() and throw() must not violate the entry/exit criteria.
10803
208
    CS->getCapturedDecl()->setNothrow();
10804
208
  }
10805
10806
208
  OMPLoopDirective::HelperExprs B;
10807
  // In presence of clause 'collapse', it will define the nested loops number.
10808
208
  unsigned NestedLoopCount =
10809
208
      checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10810
208
                      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10811
208
                      VarsWithImplicitDSA, B);
10812
208
  if (NestedLoopCount == 0)
10813
3
    return StmtError();
10814
10815
205
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10816
205
         "omp loop exprs were not built");
10817
10818
205
  setFunctionHasBranchProtectedScope();
10819
205
  DSAStack->setParentTeamsRegionLoc(StartLoc);
10820
10821
205
  return OMPTeamsGenericLoopDirective::Create(
10822
205
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10823
205
}
10824
10825
StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective(
10826
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10827
523
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10828
523
  if (!AStmt)
10829
0
    return StmtError();
10830
10831
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10832
  // A list item may not appear in a lastprivate clause unless it is the
10833
  // loop iteration variable of a loop that is associated with the construct.
10834
523
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10835
523
                                  DSAStack))
10836
3
    return StmtError();
10837
10838
520
  auto *CS = cast<CapturedStmt>(AStmt);
10839
  // 1.2.2 OpenMP Language Terminology
10840
  // Structured block - An executable statement with a single entry at the
10841
  // top and a single exit at the bottom.
10842
  // The point of exit cannot be a branch out of the structured block.
10843
  // longjmp() and throw() must not violate the entry/exit criteria.
10844
520
  CS->getCapturedDecl()->setNothrow();
10845
520
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10846
2.08k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel1.56k
) {
10847
1.56k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
10848
    // 1.2.2 OpenMP Language Terminology
10849
    // Structured block - An executable statement with a single entry at the
10850
    // top and a single exit at the bottom.
10851
    // The point of exit cannot be a branch out of the structured block.
10852
    // longjmp() and throw() must not violate the entry/exit criteria.
10853
1.56k
    CS->getCapturedDecl()->setNothrow();
10854
1.56k
  }
10855
10856
520
  OMPLoopDirective::HelperExprs B;
10857
  // In presence of clause 'collapse', it will define the nested loops number.
10858
520
  unsigned NestedLoopCount =
10859
520
      checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10860
520
                      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10861
520
                      VarsWithImplicitDSA, B);
10862
520
  if (NestedLoopCount == 0)
10863
3
    return StmtError();
10864
10865
517
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10866
517
         "omp loop exprs were not built");
10867
10868
517
  setFunctionHasBranchProtectedScope();
10869
10870
517
  return OMPTargetTeamsGenericLoopDirective::Create(
10871
517
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10872
517
}
10873
10874
StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective(
10875
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10876
49
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10877
49
  if (!AStmt)
10878
0
    return StmtError();
10879
10880
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10881
  // A list item may not appear in a lastprivate clause unless it is the
10882
  // loop iteration variable of a loop that is associated with the construct.
10883
49
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack))
10884
3
    return StmtError();
10885
10886
46
  auto *CS = cast<CapturedStmt>(AStmt);
10887
  // 1.2.2 OpenMP Language Terminology
10888
  // Structured block - An executable statement with a single entry at the
10889
  // top and a single exit at the bottom.
10890
  // The point of exit cannot be a branch out of the structured block.
10891
  // longjmp() and throw() must not violate the entry/exit criteria.
10892
46
  CS->getCapturedDecl()->setNothrow();
10893
46
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10894
46
       ThisCaptureLevel > 1; 
--ThisCaptureLevel0
) {
10895
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
10896
    // 1.2.2 OpenMP Language Terminology
10897
    // Structured block - An executable statement with a single entry at the
10898
    // top and a single exit at the bottom.
10899
    // The point of exit cannot be a branch out of the structured block.
10900
    // longjmp() and throw() must not violate the entry/exit criteria.
10901
0
    CS->getCapturedDecl()->setNothrow();
10902
0
  }
10903
10904
46
  OMPLoopDirective::HelperExprs B;
10905
  // In presence of clause 'collapse', it will define the nested loops number.
10906
46
  unsigned NestedLoopCount =
10907
46
      checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10908
46
                      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10909
46
                      VarsWithImplicitDSA, B);
10910
46
  if (NestedLoopCount == 0)
10911
3
    return StmtError();
10912
10913
43
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10914
43
         "omp loop exprs were not built");
10915
10916
43
  setFunctionHasBranchProtectedScope();
10917
10918
43
  return OMPParallelGenericLoopDirective::Create(
10919
43
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10920
43
}
10921
10922
StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective(
10923
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10924
871
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10925
871
  if (!AStmt)
10926
0
    return StmtError();
10927
10928
  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10929
  // A list item may not appear in a lastprivate clause unless it is the
10930
  // loop iteration variable of a loop that is associated with the construct.
10931
871
  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10932
871
                                  DSAStack))
10933
3
    return StmtError();
10934
10935
868
  auto *CS = cast<CapturedStmt>(AStmt);
10936
  // 1.2.2 OpenMP Language Terminology
10937
  // Structured block - An executable statement with a single entry at the
10938
  // top and a single exit at the bottom.
10939
  // The point of exit cannot be a branch out of the structured block.
10940
  // longjmp() and throw() must not violate the entry/exit criteria.
10941
868
  CS->getCapturedDecl()->setNothrow();
10942
868
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10943
2.60k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel1.73k
) {
10944
1.73k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
10945
    // 1.2.2 OpenMP Language Terminology
10946
    // Structured block - An executable statement with a single entry at the
10947
    // top and a single exit at the bottom.
10948
    // The point of exit cannot be a branch out of the structured block.
10949
    // longjmp() and throw() must not violate the entry/exit criteria.
10950
1.73k
    CS->getCapturedDecl()->setNothrow();
10951
1.73k
  }
10952
10953
868
  OMPLoopDirective::HelperExprs B;
10954
  // In presence of clause 'collapse', it will define the nested loops number.
10955
868
  unsigned NestedLoopCount =
10956
868
      checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10957
868
                      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10958
868
                      VarsWithImplicitDSA, B);
10959
868
  if (NestedLoopCount == 0)
10960
3
    return StmtError();
10961
10962
865
  assert((CurContext->isDependentContext() || B.builtAll()) &&
10963
865
         "omp loop exprs were not built");
10964
10965
865
  setFunctionHasBranchProtectedScope();
10966
10967
865
  return OMPTargetParallelGenericLoopDirective::Create(
10968
865
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10969
865
}
10970
10971
StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10972
                                            Stmt *AStmt,
10973
                                            SourceLocation StartLoc,
10974
2.49k
                                            SourceLocation EndLoc) {
10975
2.49k
  if (!AStmt)
10976
0
    return StmtError();
10977
10978
2.49k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10979
10980
2.49k
  setFunctionHasBranchProtectedScope();
10981
10982
  // OpenMP [2.7.3, single Construct, Restrictions]
10983
  // The copyprivate clause must not be used with the nowait clause.
10984
2.49k
  const OMPClause *Nowait = nullptr;
10985
2.49k
  const OMPClause *Copyprivate = nullptr;
10986
2.49k
  for (const OMPClause *Clause : Clauses) {
10987
494
    if (Clause->getClauseKind() == OMPC_nowait)
10988
32
      Nowait = Clause;
10989
462
    else if (Clause->getClauseKind() == OMPC_copyprivate)
10990
152
      Copyprivate = Clause;
10991
494
    if (Copyprivate && 
Nowait154
) {
10992
2
      Diag(Copyprivate->getBeginLoc(),
10993
2
           diag::err_omp_single_copyprivate_with_nowait);
10994
2
      Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10995
2
      return StmtError();
10996
2
    }
10997
494
  }
10998
10999
2.49k
  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11000
2.49k
}
11001
11002
StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
11003
                                            SourceLocation StartLoc,
11004
1.67k
                                            SourceLocation EndLoc) {
11005
1.67k
  if (!AStmt)
11006
4
    return StmtError();
11007
11008
1.67k
  setFunctionHasBranchProtectedScope();
11009
11010
1.67k
  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
11011
1.67k
}
11012
11013
StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
11014
                                            Stmt *AStmt,
11015
                                            SourceLocation StartLoc,
11016
130
                                            SourceLocation EndLoc) {
11017
130
  if (!AStmt)
11018
10
    return StmtError();
11019
11020
120
  setFunctionHasBranchProtectedScope();
11021
11022
120
  return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11023
130
}
11024
11025
StmtResult Sema::ActOnOpenMPCriticalDirective(
11026
    const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
11027
2.38k
    Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
11028
2.38k
  if (!AStmt)
11029
4
    return StmtError();
11030
11031
2.38k
  bool ErrorFound = false;
11032
2.38k
  llvm::APSInt Hint;
11033
2.38k
  SourceLocation HintLoc;
11034
2.38k
  bool DependentHint = false;
11035
2.38k
  for (const OMPClause *C : Clauses) {
11036
44
    if (C->getClauseKind() == OMPC_hint) {
11037
44
      if (!DirName.getName()) {
11038
4
        Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
11039
4
        ErrorFound = true;
11040
4
      }
11041
44
      Expr *E = cast<OMPHintClause>(C)->getHint();
11042
44
      if (E->isTypeDependent() || E->isValueDependent() ||
11043
44
          
E->isInstantiationDependent()36
) {
11044
8
        DependentHint = true;
11045
36
      } else {
11046
36
        Hint = E->EvaluateKnownConstInt(Context);
11047
36
        HintLoc = C->getBeginLoc();
11048
36
      }
11049
44
    }
11050
44
  }
11051
2.38k
  if (ErrorFound)
11052
4
    return StmtError();
11053
2.38k
  const auto Pair = DSAStack->getCriticalWithHint(DirName);
11054
2.38k
  if (Pair.first && 
DirName.getName()177
&&
!DependentHint177
) {
11055
177
    if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
11056
2
      Diag(StartLoc, diag::err_omp_critical_with_hint);
11057
2
      if (HintLoc.isValid())
11058
2
        Diag(HintLoc, diag::note_omp_critical_hint_here)
11059
2
            << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
11060
0
      else
11061
0
        Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
11062
2
      if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
11063
2
        Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
11064
2
            << 1
11065
2
            << toString(C->getHint()->EvaluateKnownConstInt(Context),
11066
2
                        /*Radix=*/10, /*Signed=*/false);
11067
2
      } else {
11068
0
        Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
11069
0
      }
11070
2
    }
11071
177
  }
11072
11073
2.38k
  setFunctionHasBranchProtectedScope();
11074
11075
2.38k
  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
11076
2.38k
                                           Clauses, AStmt);
11077
2.38k
  if (!Pair.first && 
DirName.getName()2.20k
&&
!DependentHint101
)
11078
95
    DSAStack->addCriticalWithHint(Dir, Hint);
11079
2.38k
  return Dir;
11080
2.38k
}
11081
11082
StmtResult Sema::ActOnOpenMPParallelForDirective(
11083
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11084
7.71k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11085
7.71k
  if (!AStmt)
11086
2
    return StmtError();
11087
11088
7.71k
  auto *CS = cast<CapturedStmt>(AStmt);
11089
  // 1.2.2 OpenMP Language Terminology
11090
  // Structured block - An executable statement with a single entry at the
11091
  // top and a single exit at the bottom.
11092
  // The point of exit cannot be a branch out of the structured block.
11093
  // longjmp() and throw() must not violate the entry/exit criteria.
11094
7.71k
  CS->getCapturedDecl()->setNothrow();
11095
11096
7.71k
  OMPLoopBasedDirective::HelperExprs B;
11097
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11098
  // define the nested loops number.
11099
7.71k
  unsigned NestedLoopCount =
11100
7.71k
      checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
11101
7.71k
                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
11102
7.71k
                      VarsWithImplicitDSA, B);
11103
7.71k
  if (NestedLoopCount == 0)
11104
316
    return StmtError();
11105
11106
7.40k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
11107
7.40k
         "omp parallel for loop exprs were not built");
11108
11109
7.40k
  if (!CurContext->isDependentContext()) {
11110
    // Finalize the clauses that need pre-built expressions for CodeGen.
11111
5.37k
    for (OMPClause *C : Clauses) {
11112
2.93k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
11113
165
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11114
165
                                     B.NumIterations, *this, CurScope,
11115
165
                                     DSAStack))
11116
0
          return StmtError();
11117
2.93k
    }
11118
5.37k
  }
11119
11120
7.40k
  setFunctionHasBranchProtectedScope();
11121
7.40k
  return OMPParallelForDirective::Create(
11122
7.40k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11123
7.40k
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11124
7.40k
}
11125
11126
StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
11127
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11128
8.54k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11129
8.54k
  if (!AStmt)
11130
12
    return StmtError();
11131
11132
8.52k
  auto *CS = cast<CapturedStmt>(AStmt);
11133
  // 1.2.2 OpenMP Language Terminology
11134
  // Structured block - An executable statement with a single entry at the
11135
  // top and a single exit at the bottom.
11136
  // The point of exit cannot be a branch out of the structured block.
11137
  // longjmp() and throw() must not violate the entry/exit criteria.
11138
8.52k
  CS->getCapturedDecl()->setNothrow();
11139
11140
8.52k
  OMPLoopBasedDirective::HelperExprs B;
11141
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11142
  // define the nested loops number.
11143
8.52k
  unsigned NestedLoopCount =
11144
8.52k
      checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
11145
8.52k
                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
11146
8.52k
                      VarsWithImplicitDSA, B);
11147
8.52k
  if (NestedLoopCount == 0)
11148
324
    return StmtError();
11149
11150
8.20k
  if (!CurContext->isDependentContext()) {
11151
    // Finalize the clauses that need pre-built expressions for CodeGen.
11152
6.08k
    for (OMPClause *C : Clauses) {
11153
2.41k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
11154
249
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11155
249
                                     B.NumIterations, *this, CurScope,
11156
249
                                     DSAStack))
11157
0
          return StmtError();
11158
2.41k
    }
11159
6.08k
  }
11160
11161
8.20k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
11162
12
    return StmtError();
11163
11164
8.19k
  setFunctionHasBranchProtectedScope();
11165
8.19k
  return OMPParallelForSimdDirective::Create(
11166
8.19k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11167
8.20k
}
11168
11169
StmtResult
11170
Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
11171
                                         Stmt *AStmt, SourceLocation StartLoc,
11172
5.19k
                                         SourceLocation EndLoc) {
11173
5.19k
  if (!AStmt)
11174
2
    return StmtError();
11175
11176
5.18k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11177
5.18k
  auto *CS = cast<CapturedStmt>(AStmt);
11178
  // 1.2.2 OpenMP Language Terminology
11179
  // Structured block - An executable statement with a single entry at the
11180
  // top and a single exit at the bottom.
11181
  // The point of exit cannot be a branch out of the structured block.
11182
  // longjmp() and throw() must not violate the entry/exit criteria.
11183
5.18k
  CS->getCapturedDecl()->setNothrow();
11184
11185
5.18k
  setFunctionHasBranchProtectedScope();
11186
11187
5.18k
  return OMPParallelMasterDirective::Create(
11188
5.18k
      Context, StartLoc, EndLoc, Clauses, AStmt,
11189
5.18k
      DSAStack->getTaskgroupReductionRef());
11190
5.18k
}
11191
11192
StmtResult
11193
Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses,
11194
                                         Stmt *AStmt, SourceLocation StartLoc,
11195
3.74k
                                         SourceLocation EndLoc) {
11196
3.74k
  if (!AStmt)
11197
2
    return StmtError();
11198
11199
3.74k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11200
3.74k
  auto *CS = cast<CapturedStmt>(AStmt);
11201
  // 1.2.2 OpenMP Language Terminology
11202
  // Structured block - An executable statement with a single entry at the
11203
  // top and a single exit at the bottom.
11204
  // The point of exit cannot be a branch out of the structured block.
11205
  // longjmp() and throw() must not violate the entry/exit criteria.
11206
3.74k
  CS->getCapturedDecl()->setNothrow();
11207
11208
3.74k
  setFunctionHasBranchProtectedScope();
11209
11210
3.74k
  return OMPParallelMaskedDirective::Create(
11211
3.74k
      Context, StartLoc, EndLoc, Clauses, AStmt,
11212
3.74k
      DSAStack->getTaskgroupReductionRef());
11213
3.74k
}
11214
11215
StmtResult
11216
Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
11217
                                           Stmt *AStmt, SourceLocation StartLoc,
11218
5.44k
                                           SourceLocation EndLoc) {
11219
5.44k
  if (!AStmt)
11220
0
    return StmtError();
11221
11222
5.44k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11223
5.44k
  auto BaseStmt = AStmt;
11224
10.8k
  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
11225
5.44k
    BaseStmt = CS->getCapturedStmt();
11226
5.44k
  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
11227
5.44k
    auto S = C->children();
11228
5.44k
    if (S.begin() == S.end())
11229
293
      return StmtError();
11230
    // All associated statements must be '#pragma omp section' except for
11231
    // the first one.
11232
5.14k
    for (Stmt *SectionStmt : llvm::drop_begin(S)) {
11233
49
      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
11234
2
        if (SectionStmt)
11235
2
          Diag(SectionStmt->getBeginLoc(),
11236
2
               diag::err_omp_parallel_sections_substmt_not_section);
11237
2
        return StmtError();
11238
2
      }
11239
47
      cast<OMPSectionDirective>(SectionStmt)
11240
47
          ->setHasCancel(DSAStack->isCancelRegion());
11241
47
    }
11242
5.14k
  } else {
11243
2
    Diag(AStmt->getBeginLoc(),
11244
2
         diag::err_omp_parallel_sections_not_compound_stmt);
11245
2
    return StmtError();
11246
2
  }
11247
11248
5.14k
  setFunctionHasBranchProtectedScope();
11249
11250
5.14k
  return OMPParallelSectionsDirective::Create(
11251
5.14k
      Context, StartLoc, EndLoc, Clauses, AStmt,
11252
5.14k
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11253
5.44k
}
11254
11255
/// Find and diagnose mutually exclusive clause kinds.
11256
static bool checkMutuallyExclusiveClauses(
11257
    Sema &S, ArrayRef<OMPClause *> Clauses,
11258
62.5k
    ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
11259
62.5k
  const OMPClause *PrevClause = nullptr;
11260
62.5k
  bool ErrorFound = false;
11261
62.5k
  for (const OMPClause *C : Clauses) {
11262
42.8k
    if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
11263
2.26k
      if (!PrevClause) {
11264
2.13k
        PrevClause = C;
11265
2.13k
      } else 
if (134
PrevClause->getClauseKind() != C->getClauseKind()134
) {
11266
134
        S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11267
134
            << getOpenMPClauseName(C->getClauseKind())
11268
134
            << getOpenMPClauseName(PrevClause->getClauseKind());
11269
134
        S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11270
134
            << getOpenMPClauseName(PrevClause->getClauseKind());
11271
134
        ErrorFound = true;
11272
134
      }
11273
2.26k
    }
11274
42.8k
  }
11275
62.5k
  return ErrorFound;
11276
62.5k
}
11277
11278
StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
11279
                                          Stmt *AStmt, SourceLocation StartLoc,
11280
5.44k
                                          SourceLocation EndLoc) {
11281
5.44k
  if (!AStmt)
11282
292
    return StmtError();
11283
11284
  // OpenMP 5.0, 2.10.1 task Construct
11285
  // If a detach clause appears on the directive, then a mergeable clause cannot
11286
  // appear on the same directive.
11287
5.15k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
11288
5.15k
                                    {OMPC_detach, OMPC_mergeable}))
11289
16
    return StmtError();
11290
11291
5.13k
  auto *CS = cast<CapturedStmt>(AStmt);
11292
  // 1.2.2 OpenMP Language Terminology
11293
  // Structured block - An executable statement with a single entry at the
11294
  // top and a single exit at the bottom.
11295
  // The point of exit cannot be a branch out of the structured block.
11296
  // longjmp() and throw() must not violate the entry/exit criteria.
11297
5.13k
  CS->getCapturedDecl()->setNothrow();
11298
11299
5.13k
  setFunctionHasBranchProtectedScope();
11300
11301
5.13k
  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11302
5.13k
                                  DSAStack->isCancelRegion());
11303
5.15k
}
11304
11305
StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
11306
855
                                               SourceLocation EndLoc) {
11307
855
  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
11308
855
}
11309
11310
StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
11311
443
                                             SourceLocation EndLoc) {
11312
443
  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
11313
443
}
11314
11315
StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
11316
                                           SourceLocation StartLoc,
11317
                                           SourceLocation EndLoc,
11318
168
                                           bool InExContext) {
11319
168
  const OMPAtClause *AtC =
11320
168
      OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11321
11322
168
  if (AtC && 
!InExContext86
&&
AtC->getAtKind() == OMPC_AT_execution8
) {
11323
4
    Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
11324
4
    return StmtError();
11325
4
  }
11326
11327
164
  const OMPSeverityClause *SeverityC =
11328
164
      OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11329
164
  const OMPMessageClause *MessageC =
11330
164
      OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11331
164
  Expr *ME = MessageC ? 
MessageC->getMessageString()66
:
nullptr98
;
11332
11333
164
  if (!AtC || 
AtC->getAtKind() == OMPC_AT_compilation82
) {
11334
104
    if (SeverityC && 
SeverityC->getSeverityKind() == OMPC_SEVERITY_warning32
)
11335
20
      Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
11336
20
          << (ME ? 
cast<StringLiteral>(ME)->getString()8
:
"WARNING"12
);
11337
84
    else
11338
84
      Diag(StartLoc, diag::err_diagnose_if_succeeded)
11339
84
          << (ME ? 
cast<StringLiteral>(ME)->getString()10
:
"ERROR"74
);
11340
104
    if (!SeverityC || 
SeverityC->getSeverityKind() != OMPC_SEVERITY_warning32
)
11341
84
      return StmtError();
11342
104
  }
11343
80
  return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
11344
164
}
11345
11346
StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
11347
                                              SourceLocation StartLoc,
11348
1.03k
                                              SourceLocation EndLoc) {
11349
1.03k
  const OMPNowaitClause *NowaitC =
11350
1.03k
      OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11351
1.03k
  bool HasDependC =
11352
1.03k
      !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11353
1.03k
           .empty();
11354
1.03k
  if (NowaitC && 
!HasDependC32
) {
11355
0
    Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11356
0
    return StmtError();
11357
0
  }
11358
11359
1.03k
  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
11360
1.03k
}
11361
11362
StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
11363
                                               Stmt *AStmt,
11364
                                               SourceLocation StartLoc,
11365
8.60k
                                               SourceLocation EndLoc) {
11366
8.60k
  if (!AStmt)
11367
2
    return StmtError();
11368
11369
8.60k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11370
11371
8.60k
  setFunctionHasBranchProtectedScope();
11372
11373
8.60k
  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
11374
8.60k
                                       AStmt,
11375
8.60k
                                       DSAStack->getTaskgroupReductionRef());
11376
8.60k
}
11377
11378
StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
11379
                                           SourceLocation StartLoc,
11380
1.15k
                                           SourceLocation EndLoc) {
11381
1.15k
  OMPFlushClause *FC = nullptr;
11382
1.15k
  OMPClause *OrderClause = nullptr;
11383
1.15k
  for (OMPClause *C : Clauses) {
11384
206
    if (C->getClauseKind() == OMPC_flush)
11385
86
      FC = cast<OMPFlushClause>(C);
11386
120
    else
11387
120
      OrderClause = C;
11388
206
  }
11389
1.15k
  OpenMPClauseKind MemOrderKind = OMPC_unknown;
11390
1.15k
  SourceLocation MemOrderLoc;
11391
1.15k
  for (const OMPClause *C : Clauses) {
11392
206
    if (C->getClauseKind() == OMPC_acq_rel ||
11393
206
        
C->getClauseKind() == OMPC_acquire164
||
11394
206
        
C->getClauseKind() == OMPC_release124
) {
11395
120
      if (MemOrderKind != OMPC_unknown) {
11396
4
        Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11397
4
            << getOpenMPDirectiveName(OMPD_flush) << 1
11398
4
            << SourceRange(C->getBeginLoc(), C->getEndLoc());
11399
4
        Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11400
4
            << getOpenMPClauseName(MemOrderKind);
11401
116
      } else {
11402
116
        MemOrderKind = C->getClauseKind();
11403
116
        MemOrderLoc = C->getBeginLoc();
11404
116
      }
11405
120
    }
11406
206
  }
11407
1.15k
  if (FC && 
OrderClause86
) {
11408
2
    Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
11409
2
        << getOpenMPClauseName(OrderClause->getClauseKind());
11410
2
    Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
11411
2
        << getOpenMPClauseName(OrderClause->getClauseKind());
11412
2
    return StmtError();
11413
2
  }
11414
1.15k
  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
11415
1.15k
}
11416
11417
StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
11418
                                            SourceLocation StartLoc,
11419
648
                                            SourceLocation EndLoc) {
11420
648
  if (Clauses.empty()) {
11421
62
    Diag(StartLoc, diag::err_omp_depobj_expected);
11422
62
    return StmtError();
11423
586
  } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11424
10
    Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11425
10
    return StmtError();
11426
10
  }
11427
  // Only depobj expression and another single clause is allowed.
11428
576
  if (Clauses.size() > 2) {
11429
24
    Diag(Clauses[2]->getBeginLoc(),
11430
24
         diag::err_omp_depobj_single_clause_expected);
11431
24
    return StmtError();
11432
552
  } else if (Clauses.size() < 1) {
11433
0
    Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11434
0
    return StmtError();
11435
0
  }
11436
552
  return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
11437
576
}
11438
11439
StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
11440
                                          SourceLocation StartLoc,
11441
285
                                          SourceLocation EndLoc) {
11442
  // Check that exactly one clause is specified.
11443
285
  if (Clauses.size() != 1) {
11444
68
    Diag(Clauses.empty() ? 
EndLoc62
:
Clauses[1]->getBeginLoc()6
,
11445
68
         diag::err_omp_scan_single_clause_expected);
11446
68
    return StmtError();
11447
68
  }
11448
  // Check that scan directive is used in the scopeof the OpenMP loop body.
11449
217
  if (Scope *S = DSAStack->getCurScope()) {
11450
205
    Scope *ParentS = S->getParent();
11451
205
    if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
11452
205
        
!ParentS->getBreakParent()->isOpenMPLoopScope()193
)
11453
40
      return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11454
40
                       << getOpenMPDirectiveName(OMPD_scan) << 5);
11455
205
  }
11456
  // Check that only one instance of scan directives is used in the same outer
11457
  // region.
11458
177
  if (DSAStack->doesParentHasScanDirective()) {
11459
4
    Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
11460
4
    Diag(DSAStack->getParentScanDirectiveLoc(),
11461
4
         diag::note_omp_previous_directive)
11462
4
        << "scan";
11463
4
    return StmtError();
11464
4
  }
11465
173
  DSAStack->setParentHasScanDirective(StartLoc);
11466
173
  return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
11467
177
}
11468
11469
StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
11470
                                             Stmt *AStmt,
11471
                                             SourceLocation StartLoc,
11472
2.24k
                                             SourceLocation EndLoc) {
11473
2.24k
  const OMPClause *DependFound = nullptr;
11474
2.24k
  const OMPClause *DependSourceClause = nullptr;
11475
2.24k
  const OMPClause *DependSinkClause = nullptr;
11476
2.24k
  const OMPClause *DoacrossFound = nullptr;
11477
2.24k
  const OMPClause *DoacrossSourceClause = nullptr;
11478
2.24k
  const OMPClause *DoacrossSinkClause = nullptr;
11479
2.24k
  bool ErrorFound = false;
11480
2.24k
  const OMPThreadsClause *TC = nullptr;
11481
2.24k
  const OMPSIMDClause *SC = nullptr;
11482
2.24k
  for (const OMPClause *C : Clauses) {
11483
987
    auto DOC = dyn_cast<OMPDoacrossClause>(C);
11484
987
    auto DC = dyn_cast<OMPDependClause>(C);
11485
987
    if (DC || 
DOC451
) {
11486
655
      DependFound = DC ? 
C536
:
nullptr119
;
11487
655
      DoacrossFound = DOC ? 
C119
:
nullptr536
;
11488
655
      OMPDoacrossKind ODK;
11489
655
      if ((DC && 
DC->getDependencyKind() == OMPC_DEPEND_source536
) ||
11490
655
          
(449
DOC449
&&
(ODK.isSource(DOC))119
)) {
11491
254
        if ((DC && 
DependSourceClause206
) ||
(242
DOC242
&&
DoacrossSourceClause48
)) {
11492
14
          Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
11493
14
              << getOpenMPDirectiveName(OMPD_ordered)
11494
14
              << getOpenMPClauseName(DC ? 
OMPC_depend12
:
OMPC_doacross2
) << 2;
11495
14
          ErrorFound = true;
11496
240
        } else {
11497
240
          if (DC)
11498
194
            DependSourceClause = C;
11499
46
          else
11500
46
            DoacrossSourceClause = C;
11501
240
        }
11502
254
        if ((DC && 
DependSinkClause206
) ||
(242
DOC242
&&
DoacrossSinkClause48
)) {
11503
14
          Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11504
14
              << (DC ? 
"depend"12
:
"doacross"2
) << 0;
11505
14
          ErrorFound = true;
11506
14
        }
11507
401
      } else if ((DC && 
DC->getDependencyKind() == OMPC_DEPEND_sink330
) ||
11508
401
                 
(71
DOC71
&&
(71
ODK.isSink(DOC)71
||
ODK.isSinkIter(DOC)17
))) {
11509
401
        if (DependSourceClause || 
DoacrossSourceClause389
) {
11510
14
          Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11511
14
              << (DC ? 
"depend"12
:
"doacross"2
) << 1;
11512
14
          ErrorFound = true;
11513
14
        }
11514
401
        if (DC)
11515
330
          DependSinkClause = C;
11516
71
        else
11517
71
          DoacrossSinkClause = C;
11518
401
      }
11519
655
    } else 
if (332
C->getClauseKind() == OMPC_threads332
) {
11520
147
      TC = cast<OMPThreadsClause>(C);
11521
185
    } else if (C->getClauseKind() == OMPC_simd) {
11522
185
      SC = cast<OMPSIMDClause>(C);
11523
185
    }
11524
987
  }
11525
2.24k
  if (!ErrorFound && 
!SC2.20k
&&
11526
2.24k
      
isOpenMPSimdDirective(2.01k
DSAStack2.01k
->getParentDirective())) {
11527
    // OpenMP [2.8.1,simd Construct, Restrictions]
11528
    // An ordered construct with the simd clause is the only OpenMP construct
11529
    // that can appear in the simd region.
11530
314
    Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11531
314
        << (LangOpts.OpenMP >= 50 ? 
1218
:
096
);
11532
314
    ErrorFound = true;
11533
1.93k
  } else if ((DependFound || 
DoacrossFound1.47k
) &&
(566
TC566
||
SC552
)) {
11534
28
    SourceLocation Loc =
11535
28
        DependFound ? 
DependFound->getBeginLoc()24
:
DoacrossFound->getBeginLoc()4
;
11536
28
    Diag(Loc, diag::err_omp_depend_clause_thread_simd)
11537
28
        << getOpenMPClauseName(DependFound ? 
OMPC_depend24
:
OMPC_doacross4
)
11538
28
        << getOpenMPClauseName(TC ? 
TC->getClauseKind()14
:
SC->getClauseKind()14
);
11539
28
    ErrorFound = true;
11540
1.90k
  } else if ((DependFound || 
DoacrossFound1.47k
) &&
11541
1.90k
             
!538
DSAStack538
->getParentOrderedRegionParam().first) {
11542
38
    SourceLocation Loc =
11543
38
        DependFound ? 
DependFound->getBeginLoc()36
:
DoacrossFound->getBeginLoc()2
;
11544
38
    Diag(Loc, diag::err_omp_ordered_directive_without_param)
11545
38
        << getOpenMPClauseName(DependFound ? 
OMPC_depend36
:
OMPC_doacross2
);
11546
38
    ErrorFound = true;
11547
1.86k
  } else if (TC || 
Clauses.empty()1.79k
) {
11548
1.19k
    if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
11549
70
      SourceLocation ErrLoc = TC ? 
TC->getBeginLoc()14
:
StartLoc56
;
11550
70
      Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11551
70
          << (TC != nullptr);
11552
70
      Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11553
70
      ErrorFound = true;
11554
70
    }
11555
1.19k
  }
11556
2.24k
  if ((!AStmt && 
!DependFound622
&&
!DoacrossFound152
) ||
ErrorFound2.20k
)
11557
492
    return StmtError();
11558
11559
  // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11560
  // During execution of an iteration of a worksharing-loop or a loop nest
11561
  // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11562
  // must not execute more than one ordered region corresponding to an ordered
11563
  // construct without a depend clause.
11564
1.75k
  if (!DependFound && 
!DoacrossFound1.39k
) {
11565
1.29k
    if (DSAStack->doesParentHasOrderedDirective()) {
11566
14
      Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
11567
14
      Diag(DSAStack->getParentOrderedDirectiveLoc(),
11568
14
           diag::note_omp_previous_directive)
11569
14
          << "ordered";
11570
14
      return StmtError();
11571
14
    }
11572
1.28k
    DSAStack->setParentHasOrderedDirective(StartLoc);
11573
1.28k
  }
11574
11575
1.74k
  if (AStmt) {
11576
1.28k
    assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11577
11578
1.28k
    setFunctionHasBranchProtectedScope();
11579
1.28k
  }
11580
11581
1.74k
  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11582
1.74k
}
11583
11584
namespace {
11585
/// Helper class for checking expression in 'omp atomic [update]'
11586
/// construct.
11587
class OpenMPAtomicUpdateChecker {
11588
  /// Error results for atomic update expressions.
11589
  enum ExprAnalysisErrorCode {
11590
    /// A statement is not an expression statement.
11591
    NotAnExpression,
11592
    /// Expression is not builtin binary or unary operation.
11593
    NotABinaryOrUnaryExpression,
11594
    /// Unary operation is not post-/pre- increment/decrement operation.
11595
    NotAnUnaryIncDecExpression,
11596
    /// An expression is not of scalar type.
11597
    NotAScalarType,
11598
    /// A binary operation is not an assignment operation.
11599
    NotAnAssignmentOp,
11600
    /// RHS part of the binary operation is not a binary expression.
11601
    NotABinaryExpression,
11602
    /// RHS part is not additive/multiplicative/shift/biwise binary
11603
    /// expression.
11604
    NotABinaryOperator,
11605
    /// RHS binary operation does not have reference to the updated LHS
11606
    /// part.
11607
    NotAnUpdateExpression,
11608
    /// An expression contains semantical error not related to
11609
    /// 'omp atomic [update]'
11610
    NotAValidExpression,
11611
    /// No errors is found.
11612
    NoError
11613
  };
11614
  /// Reference to Sema.
11615
  Sema &SemaRef;
11616
  /// A location for note diagnostics (when error is found).
11617
  SourceLocation NoteLoc;
11618
  /// 'x' lvalue part of the source atomic expression.
11619
  Expr *X;
11620
  /// 'expr' rvalue part of the source atomic expression.
11621
  Expr *E;
11622
  /// Helper expression of the form
11623
  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11624
  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11625
  Expr *UpdateExpr;
11626
  /// Is 'x' a LHS in a RHS part of full update expression. It is
11627
  /// important for non-associative operations.
11628
  bool IsXLHSInRHSPart;
11629
  BinaryOperatorKind Op;
11630
  SourceLocation OpLoc;
11631
  /// true if the source expression is a postfix unary operation, false
11632
  /// if it is a prefix unary operation.
11633
  bool IsPostfixUpdate;
11634
11635
public:
11636
  OpenMPAtomicUpdateChecker(Sema &SemaRef)
11637
5.45k
      : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11638
5.45k
        IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11639
  /// Check specified statement that it is suitable for 'atomic update'
11640
  /// constructs and extract 'x', 'expr' and Operation from the original
11641
  /// expression. If DiagId and NoteId == 0, then only check is performed
11642
  /// without error notification.
11643
  /// \param DiagId Diagnostic which should be emitted if error is found.
11644
  /// \param NoteId Diagnostic note for the main error message.
11645
  /// \return true if statement is not an update expression, false otherwise.
11646
  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11647
  /// Return the 'x' lvalue part of the source atomic expression.
11648
4.16k
  Expr *getX() const { return X; }
11649
  /// Return the 'expr' rvalue part of the source atomic expression.
11650
3.34k
  Expr *getExpr() const { return E; }
11651
  /// Return the update expression used in calculation of the updated
11652
  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11653
  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11654
3.34k
  Expr *getUpdateExpr() const { return UpdateExpr; }
11655
  /// Return true if 'x' is LHS in RHS part of full update expression,
11656
  /// false otherwise.
11657
3.34k
  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11658
11659
  /// true if the source expression is a postfix unary operation, false
11660
  /// if it is a prefix unary operation.
11661
954
  bool isPostfixUpdate() const { return IsPostfixUpdate; }
11662
11663
private:
11664
  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11665
                            unsigned NoteId = 0);
11666
};
11667
11668
bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11669
2.05k
    BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11670
2.05k
  ExprAnalysisErrorCode ErrorFound = NoError;
11671
2.05k
  SourceLocation ErrorLoc, NoteLoc;
11672
2.05k
  SourceRange ErrorRange, NoteRange;
11673
  // Allowed constructs are:
11674
  //  x = x binop expr;
11675
  //  x = expr binop x;
11676
2.05k
  if (AtomicBinOp->getOpcode() == BO_Assign) {
11677
1.98k
    X = AtomicBinOp->getLHS();
11678
1.98k
    if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11679
1.98k
            AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11680
1.40k
      if (AtomicInnerBinOp->isMultiplicativeOp() ||
11681
1.40k
          
AtomicInnerBinOp->isAdditiveOp()1.10k
||
AtomicInnerBinOp->isShiftOp()534
||
11682
1.40k
          
AtomicInnerBinOp->isBitwiseOp()366
) {
11683
1.30k
        Op = AtomicInnerBinOp->getOpcode();
11684
1.30k
        OpLoc = AtomicInnerBinOp->getOperatorLoc();
11685
1.30k
        Expr *LHS = AtomicInnerBinOp->getLHS();
11686
1.30k
        Expr *RHS = AtomicInnerBinOp->getRHS();
11687
1.30k
        llvm::FoldingSetNodeID XId, LHSId, RHSId;
11688
1.30k
        X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11689
1.30k
                                          /*Canonical=*/true);
11690
1.30k
        LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11691
1.30k
                                            /*Canonical=*/true);
11692
1.30k
        RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11693
1.30k
                                            /*Canonical=*/true);
11694
1.30k
        if (XId == LHSId) {
11695
667
          E = RHS;
11696
667
          IsXLHSInRHSPart = true;
11697
667
        } else 
if (636
XId == RHSId636
) {
11698
528
          E = LHS;
11699
528
          IsXLHSInRHSPart = false;
11700
528
        } else {
11701
108
          ErrorLoc = AtomicInnerBinOp->getExprLoc();
11702
108
          ErrorRange = AtomicInnerBinOp->getSourceRange();
11703
108
          NoteLoc = X->getExprLoc();
11704
108
          NoteRange = X->getSourceRange();
11705
108
          ErrorFound = NotAnUpdateExpression;
11706
108
        }
11707
1.30k
      } else {
11708
102
        ErrorLoc = AtomicInnerBinOp->getExprLoc();
11709
102
        ErrorRange = AtomicInnerBinOp->getSourceRange();
11710
102
        NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11711
102
        NoteRange = SourceRange(NoteLoc, NoteLoc);
11712
102
        ErrorFound = NotABinaryOperator;
11713
102
      }
11714
1.40k
    } else {
11715
579
      NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11716
579
      NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11717
579
      ErrorFound = NotABinaryExpression;
11718
579
    }
11719
1.98k
  } else {
11720
72
    ErrorLoc = AtomicBinOp->getExprLoc();
11721
72
    ErrorRange = AtomicBinOp->getSourceRange();
11722
72
    NoteLoc = AtomicBinOp->getOperatorLoc();
11723
72
    NoteRange = SourceRange(NoteLoc, NoteLoc);
11724
72
    ErrorFound = NotAnAssignmentOp;
11725
72
  }
11726
2.05k
  if (ErrorFound != NoError && 
DiagId != 0861
&&
NoteId != 0252
) {
11727
252
    SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11728
252
    SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11729
252
    return true;
11730
252
  }
11731
1.80k
  if (SemaRef.CurContext->isDependentContext())
11732
362
    E = X = UpdateExpr = nullptr;
11733
1.80k
  return ErrorFound != NoError;
11734
2.05k
}
11735
11736
bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11737
5.95k
                                               unsigned NoteId) {
11738
5.95k
  ExprAnalysisErrorCode ErrorFound = NoError;
11739
5.95k
  SourceLocation ErrorLoc, NoteLoc;
11740
5.95k
  SourceRange ErrorRange, NoteRange;
11741
  // Allowed constructs are:
11742
  //  x++;
11743
  //  x--;
11744
  //  ++x;
11745
  //  --x;
11746
  //  x binop= expr;
11747
  //  x = x binop expr;
11748
  //  x = expr binop x;
11749
5.95k
  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11750
5.00k
    AtomicBody = AtomicBody->IgnoreParenImpCasts();
11751
5.00k
    if (AtomicBody->getType()->isScalarType() ||
11752
5.00k
        
AtomicBody->isInstantiationDependent()1.20k
) {
11753
5.00k
      if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11754
5.00k
              AtomicBody->IgnoreParenImpCasts())) {
11755
        // Check for Compound Assignment Operation
11756
1.24k
        Op = BinaryOperator::getOpForCompoundAssignment(
11757
1.24k
            AtomicCompAssignOp->getOpcode());
11758
1.24k
        OpLoc = AtomicCompAssignOp->getOperatorLoc();
11759
1.24k
        E = AtomicCompAssignOp->getRHS();
11760
1.24k
        X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11761
1.24k
        IsXLHSInRHSPart = true;
11762
3.76k
      } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11763
3.76k
                     AtomicBody->IgnoreParenImpCasts())) {
11764
        // Check for Binary Operation
11765
2.05k
        if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11766
861
          return true;
11767
2.05k
      } else 
if (const auto *1.71k
AtomicUnaryOp1.71k
= dyn_cast<UnaryOperator>(
11768
1.71k
                     AtomicBody->IgnoreParenImpCasts())) {
11769
        // Check for Unary Operation
11770
1.67k
        if (AtomicUnaryOp->isIncrementDecrementOp()) {
11771
1.67k
          IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11772
1.67k
          Op = AtomicUnaryOp->isIncrementOp() ? 
BO_Add1.51k
:
BO_Sub168
;
11773
1.67k
          OpLoc = AtomicUnaryOp->getOperatorLoc();
11774
1.67k
          X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11775
1.67k
          E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11776
1.67k
          IsXLHSInRHSPart = true;
11777
1.67k
        } else {
11778
0
          ErrorFound = NotAnUnaryIncDecExpression;
11779
0
          ErrorLoc = AtomicUnaryOp->getExprLoc();
11780
0
          ErrorRange = AtomicUnaryOp->getSourceRange();
11781
0
          NoteLoc = AtomicUnaryOp->getOperatorLoc();
11782
0
          NoteRange = SourceRange(NoteLoc, NoteLoc);
11783
0
        }
11784
1.67k
      } else 
if (31
!AtomicBody->isInstantiationDependent()31
) {
11785
24
        ErrorFound = NotABinaryOrUnaryExpression;
11786
24
        NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11787
24
        NoteRange = ErrorRange = AtomicBody->getSourceRange();
11788
24
      } else 
if (7
AtomicBody->containsErrors()7
) {
11789
1
        ErrorFound = NotAValidExpression;
11790
1
        NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11791
1
        NoteRange = ErrorRange = AtomicBody->getSourceRange();
11792
1
      }
11793
5.00k
    } else {
11794
0
      ErrorFound = NotAScalarType;
11795
0
      NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11796
0
      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11797
0
    }
11798
5.00k
  } else {
11799
951
    ErrorFound = NotAnExpression;
11800
951
    NoteLoc = ErrorLoc = S->getBeginLoc();
11801
951
    NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11802
951
  }
11803
5.09k
  if (ErrorFound != NoError && 
DiagId != 0976
&&
NoteId != 0975
) {
11804
975
    SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11805
975
    SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11806
975
    return true;
11807
975
  }
11808
4.12k
  if (SemaRef.CurContext->isDependentContext())
11809
1.00k
    E = X = UpdateExpr = nullptr;
11810
4.12k
  if (ErrorFound == NoError && 
E4.12k
&&
X3.12k
) {
11811
    // Build an update expression of form 'OpaqueValueExpr(x) binop
11812
    // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11813
    // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11814
3.12k
    auto *OVEX = new (SemaRef.getASTContext())
11815
3.12k
        OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11816
3.12k
    auto *OVEExpr = new (SemaRef.getASTContext())
11817
3.12k
        OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
11818
3.12k
    ExprResult Update =
11819
3.12k
        SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? 
OVEX2.69k
:
OVEExpr432
,
11820
3.12k
                                   IsXLHSInRHSPart ? 
OVEExpr2.69k
:
OVEX432
);
11821
3.12k
    if (Update.isInvalid())
11822
0
      return true;
11823
3.12k
    Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11824
3.12k
                                               Sema::AA_Casting);
11825
3.12k
    if (Update.isInvalid())
11826
0
      return true;
11827
3.12k
    UpdateExpr = Update.get();
11828
3.12k
  }
11829
4.12k
  return ErrorFound != NoError;
11830
4.12k
}
11831
11832
/// Get the node id of the fixed point of an expression \a S.
11833
80.3k
llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11834
80.3k
  llvm::FoldingSetNodeID Id;
11835
80.3k
  S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11836
80.3k
  return Id;
11837
80.3k
}
11838
11839
/// Check if two expressions are same.
11840
bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11841
40.1k
                            const Expr *RHS) {
11842
40.1k
  return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11843
40.1k
}
11844
11845
class OpenMPAtomicCompareChecker {
11846
public:
11847
  /// All kinds of errors that can occur in `atomic compare`
11848
  enum ErrorTy {
11849
    /// Empty compound statement.
11850
    NoStmt = 0,
11851
    /// More than one statement in a compound statement.
11852
    MoreThanOneStmt,
11853
    /// Not an assignment binary operator.
11854
    NotAnAssignment,
11855
    /// Not a conditional operator.
11856
    NotCondOp,
11857
    /// Wrong false expr. According to the spec, 'x' should be at the false
11858
    /// expression of a conditional expression.
11859
    WrongFalseExpr,
11860
    /// The condition of a conditional expression is not a binary operator.
11861
    NotABinaryOp,
11862
    /// Invalid binary operator (not <, >, or ==).
11863
    InvalidBinaryOp,
11864
    /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11865
    InvalidComparison,
11866
    /// X is not a lvalue.
11867
    XNotLValue,
11868
    /// Not a scalar.
11869
    NotScalar,
11870
    /// Not an integer.
11871
    NotInteger,
11872
    /// 'else' statement is not expected.
11873
    UnexpectedElse,
11874
    /// Not an equality operator.
11875
    NotEQ,
11876
    /// Invalid assignment (not v == x).
11877
    InvalidAssignment,
11878
    /// Not if statement
11879
    NotIfStmt,
11880
    /// More than two statements in a compund statement.
11881
    MoreThanTwoStmts,
11882
    /// Not a compound statement.
11883
    NotCompoundStmt,
11884
    /// No else statement.
11885
    NoElse,
11886
    /// Not 'if (r)'.
11887
    InvalidCondition,
11888
    /// No error.
11889
    NoError,
11890
  };
11891
11892
  struct ErrorInfoTy {
11893
    ErrorTy Error;
11894
    SourceLocation ErrorLoc;
11895
    SourceRange ErrorRange;
11896
    SourceLocation NoteLoc;
11897
    SourceRange NoteRange;
11898
  };
11899
11900
13.7k
  OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11901
11902
  /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11903
  bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11904
11905
13.6k
  Expr *getX() const { return X; }
11906
13.6k
  Expr *getE() const { return E; }
11907
13.6k
  Expr *getD() const { return D; }
11908
13.6k
  Expr *getCond() const { return C; }
11909
13.6k
  bool isXBinopExpr() const { return IsXBinopExpr; }
11910
11911
protected:
11912
  /// Reference to ASTContext
11913
  ASTContext &ContextRef;
11914
  /// 'x' lvalue part of the source atomic expression.
11915
  Expr *X = nullptr;
11916
  /// 'expr' or 'e' rvalue part of the source atomic expression.
11917
  Expr *E = nullptr;
11918
  /// 'd' rvalue part of the source atomic expression.
11919
  Expr *D = nullptr;
11920
  /// 'cond' part of the source atomic expression. It is in one of the following
11921
  /// forms:
11922
  /// expr ordop x
11923
  /// x ordop expr
11924
  /// x == e
11925
  /// e == x
11926
  Expr *C = nullptr;
11927
  /// True if the cond expr is in the form of 'x ordop expr'.
11928
  bool IsXBinopExpr = true;
11929
11930
  /// Check if it is a valid conditional update statement (cond-update-stmt).
11931
  bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11932
11933
  /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11934
  bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11935
11936
  /// Check if all captured values have right type.
11937
  bool checkType(ErrorInfoTy &ErrorInfo) const;
11938
11939
  static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11940
44.4k
                         bool ShouldBeLValue, bool ShouldBeInteger = false) {
11941
44.4k
    if (E->isInstantiationDependent())
11942
1.22k
      return true;
11943
11944
43.2k
    if (ShouldBeLValue && 
!E->isLValue()23.9k
) {
11945
0
      ErrorInfo.Error = ErrorTy::XNotLValue;
11946
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11947
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11948
0
      return false;
11949
0
    }
11950
11951
43.2k
    QualType QTy = E->getType();
11952
43.2k
    if (!QTy->isScalarType()) {
11953
0
      ErrorInfo.Error = ErrorTy::NotScalar;
11954
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11955
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11956
0
      return false;
11957
0
    }
11958
43.2k
    if (ShouldBeInteger && 
!QTy->isIntegerType()1.83k
) {
11959
2
      ErrorInfo.Error = ErrorTy::NotInteger;
11960
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11961
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11962
2
      return false;
11963
2
    }
11964
11965
43.2k
    return true;
11966
43.2k
  }
11967
  };
11968
11969
bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11970
7.14k
                                                     ErrorInfoTy &ErrorInfo) {
11971
7.14k
  auto *Then = S->getThen();
11972
7.14k
  if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11973
3.63k
    if (CS->body_empty()) {
11974
0
      ErrorInfo.Error = ErrorTy::NoStmt;
11975
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11976
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11977
0
      return false;
11978
0
    }
11979
3.63k
    if (CS->size() > 1) {
11980
0
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11981
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11982
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11983
0
      return false;
11984
0
    }
11985
3.63k
    Then = CS->body_front();
11986
3.63k
  }
11987
11988
7.14k
  auto *BO = dyn_cast<BinaryOperator>(Then);
11989
7.14k
  if (!BO) {
11990
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
11991
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11992
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11993
0
    return false;
11994
0
  }
11995
7.14k
  if (BO->getOpcode() != BO_Assign) {
11996
0
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
11997
0
    ErrorInfo.ErrorLoc = BO->getExprLoc();
11998
0
    ErrorInfo.NoteLoc = BO->getOperatorLoc();
11999
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12000
0
    return false;
12001
0
  }
12002
12003
7.14k
  X = BO->getLHS();
12004
12005
7.14k
  auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12006
7.14k
  if (!Cond) {
12007
2
    ErrorInfo.Error = ErrorTy::NotABinaryOp;
12008
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12009
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12010
2
    return false;
12011
2
  }
12012
12013
7.14k
  switch (Cond->getOpcode()) {
12014
2.26k
  case BO_EQ: {
12015
2.26k
    C = Cond;
12016
2.26k
    D = BO->getRHS();
12017
2.26k
    if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12018
1.44k
      E = Cond->getRHS();
12019
1.44k
    } else 
if (816
checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())816
) {
12020
816
      E = Cond->getLHS();
12021
816
    } else {
12022
0
      ErrorInfo.Error = ErrorTy::InvalidComparison;
12023
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12024
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12025
0
      return false;
12026
0
    }
12027
2.26k
    break;
12028
2.26k
  }
12029
2.43k
  case BO_LT:
12030
4.87k
  case BO_GT: {
12031
4.87k
    E = BO->getRHS();
12032
4.87k
    if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
12033
4.87k
        
checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())3.14k
) {
12034
3.14k
      C = Cond;
12035
3.14k
    } else 
if (1.73k
checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS())1.73k
&&
12036
1.73k
               
checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())1.72k
) {
12037
1.72k
      C = Cond;
12038
1.72k
      IsXBinopExpr = false;
12039
1.72k
    } else {
12040
2
      ErrorInfo.Error = ErrorTy::InvalidComparison;
12041
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12042
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12043
2
      return false;
12044
2
    }
12045
4.87k
    break;
12046
4.87k
  }
12047
4.87k
  default:
12048
2
    ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12049
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12050
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12051
2
    return false;
12052
7.14k
  }
12053
12054
7.14k
  if (S->getElse()) {
12055
2
    ErrorInfo.Error = ErrorTy::UnexpectedElse;
12056
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
12057
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
12058
2
    return false;
12059
2
  }
12060
12061
7.13k
  return true;
12062
7.14k
}
12063
12064
bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
12065
3.77k
                                                   ErrorInfoTy &ErrorInfo) {
12066
3.77k
  auto *BO = dyn_cast<BinaryOperator>(S);
12067
3.77k
  if (!BO) {
12068
4
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12069
4
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12070
4
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12071
4
    return false;
12072
4
  }
12073
3.76k
  if (BO->getOpcode() != BO_Assign) {
12074
2
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12075
2
    ErrorInfo.ErrorLoc = BO->getExprLoc();
12076
2
    ErrorInfo.NoteLoc = BO->getOperatorLoc();
12077
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12078
2
    return false;
12079
2
  }
12080
12081
3.76k
  X = BO->getLHS();
12082
12083
3.76k
  auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
12084
3.76k
  if (!CO) {
12085
2
    ErrorInfo.Error = ErrorTy::NotCondOp;
12086
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
12087
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
12088
2
    return false;
12089
2
  }
12090
12091
3.76k
  if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
12092
2
    ErrorInfo.Error = ErrorTy::WrongFalseExpr;
12093
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
12094
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12095
2
        CO->getFalseExpr()->getSourceRange();
12096
2
    return false;
12097
2
  }
12098
12099
3.76k
  auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
12100
3.76k
  if (!Cond) {
12101
2
    ErrorInfo.Error = ErrorTy::NotABinaryOp;
12102
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
12103
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12104
2
        CO->getCond()->getSourceRange();
12105
2
    return false;
12106
2
  }
12107
12108
3.76k
  switch (Cond->getOpcode()) {
12109
1.18k
  case BO_EQ: {
12110
1.18k
    C = Cond;
12111
1.18k
    D = CO->getTrueExpr();
12112
1.18k
    if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12113
948
      E = Cond->getRHS();
12114
948
    } else 
if (240
checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())240
) {
12115
240
      E = Cond->getLHS();
12116
240
    } else {
12117
0
      ErrorInfo.Error = ErrorTy::InvalidComparison;
12118
0
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12119
0
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12120
0
      return false;
12121
0
    }
12122
1.18k
    break;
12123
1.18k
  }
12124
1.28k
  case BO_LT:
12125
2.57k
  case BO_GT: {
12126
2.57k
    E = CO->getTrueExpr();
12127
2.57k
    if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
12128
2.57k
        
checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())1.99k
) {
12129
1.99k
      C = Cond;
12130
1.99k
    } else 
if (578
checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS())578
&&
12131
578
               
checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())576
) {
12132
576
      C = Cond;
12133
576
      IsXBinopExpr = false;
12134
576
    } else {
12135
2
      ErrorInfo.Error = ErrorTy::InvalidComparison;
12136
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12137
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12138
2
      return false;
12139
2
    }
12140
2.56k
    break;
12141
2.57k
  }
12142
2.56k
  default:
12143
2
    ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12144
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12145
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12146
2
    return false;
12147
3.76k
  }
12148
12149
3.75k
  return true;
12150
3.76k
}
12151
12152
13.6k
bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
12153
  // 'x' and 'e' cannot be nullptr
12154
13.6k
  assert(X && E && "X and E cannot be nullptr");
12155
12156
13.6k
  if (!CheckValue(X, ErrorInfo, true))
12157
0
    return false;
12158
12159
13.6k
  if (!CheckValue(E, ErrorInfo, false))
12160
0
    return false;
12161
12162
13.6k
  if (D && 
!CheckValue(D, ErrorInfo, false)6.19k
)
12163
0
    return false;
12164
12165
13.6k
  return true;
12166
13.6k
}
12167
12168
bool OpenMPAtomicCompareChecker::checkStmt(
12169
3.54k
    Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
12170
3.54k
  auto *CS = dyn_cast<CompoundStmt>(S);
12171
3.54k
  if (CS) {
12172
280
    if (CS->body_empty()) {
12173
2
      ErrorInfo.Error = ErrorTy::NoStmt;
12174
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12175
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12176
2
      return false;
12177
2
    }
12178
12179
278
    if (CS->size() != 1) {
12180
4
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12181
4
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12182
4
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12183
4
      return false;
12184
4
    }
12185
274
    S = CS->body_front();
12186
274
  }
12187
12188
3.53k
  auto Res = false;
12189
12190
3.53k
  if (auto *IS = dyn_cast<IfStmt>(S)) {
12191
    // Check if the statement is in one of the following forms
12192
    // (cond-update-stmt):
12193
    // if (expr ordop x) { x = expr; }
12194
    // if (x ordop expr) { x = expr; }
12195
    // if (x == e) { x = d; }
12196
1.64k
    Res = checkCondUpdateStmt(IS, ErrorInfo);
12197
1.89k
  } else {
12198
    // Check if the statement is in one of the following forms (cond-expr-stmt):
12199
    // x = expr ordop x ? expr : x;
12200
    // x = x ordop expr ? expr : x;
12201
    // x = x == e ? d : x;
12202
1.89k
    Res = checkCondExprStmt(S, ErrorInfo);
12203
1.89k
  }
12204
12205
3.53k
  if (!Res)
12206
22
    return false;
12207
12208
3.51k
  return checkType(ErrorInfo);
12209
3.53k
}
12210
12211
class OpenMPAtomicCompareCaptureChecker final
12212
    : public OpenMPAtomicCompareChecker {
12213
public:
12214
10.1k
  OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
12215
12216
10.1k
  Expr *getV() const { return V; }
12217
10.1k
  Expr *getR() const { return R; }
12218
10.1k
  bool isFailOnly() const { return IsFailOnly; }
12219
10.1k
  bool isPostfixUpdate() const { return IsPostfixUpdate; }
12220
12221
  /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
12222
  bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
12223
12224
private:
12225
  bool checkType(ErrorInfoTy &ErrorInfo);
12226
12227
  // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
12228
  // form of 'conditional-update-capture-atomic' structured block on the v5.2
12229
  // spec p.p. 82:
12230
  // (1) { v = x; cond-update-stmt }
12231
  // (2) { cond-update-stmt v = x; }
12232
  // (3) if(x == e) { x = d; } else { v = x; }
12233
  // (4) { r = x == e; if(r) { x = d; } }
12234
  // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
12235
12236
  /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
12237
  bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
12238
12239
  /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
12240
  /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
12241
  bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
12242
12243
  /// 'v' lvalue part of the source atomic expression.
12244
  Expr *V = nullptr;
12245
  /// 'r' lvalue part of the source atomic expression.
12246
  Expr *R = nullptr;
12247
  /// If 'v' is only updated when the comparison fails.
12248
  bool IsFailOnly = false;
12249
  /// If original value of 'x' must be stored in 'v', not an updated one.
12250
  bool IsPostfixUpdate = false;
12251
};
12252
12253
10.1k
bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
12254
10.1k
  if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
12255
0
    return false;
12256
12257
10.1k
  if (V && 
!CheckValue(V, ErrorInfo, true)9.14k
)
12258
0
    return false;
12259
12260
10.1k
  if (R && 
!CheckValue(R, ErrorInfo, true, true)1.86k
)
12261
2
    return false;
12262
12263
10.1k
  return true;
12264
10.1k
}
12265
12266
bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
12267
914
                                                   ErrorInfoTy &ErrorInfo) {
12268
914
  IsFailOnly = true;
12269
12270
914
  auto *Then = S->getThen();
12271
914
  if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
12272
602
    if (CS->body_empty()) {
12273
2
      ErrorInfo.Error = ErrorTy::NoStmt;
12274
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12275
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12276
2
      return false;
12277
2
    }
12278
600
    if (CS->size() > 1) {
12279
2
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12280
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12281
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12282
2
      return false;
12283
2
    }
12284
598
    Then = CS->body_front();
12285
598
  }
12286
12287
910
  auto *BO = dyn_cast<BinaryOperator>(Then);
12288
910
  if (!BO) {
12289
2
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12290
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12291
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12292
2
    return false;
12293
2
  }
12294
908
  if (BO->getOpcode() != BO_Assign) {
12295
2
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12296
2
    ErrorInfo.ErrorLoc = BO->getExprLoc();
12297
2
    ErrorInfo.NoteLoc = BO->getOperatorLoc();
12298
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12299
2
    return false;
12300
2
  }
12301
12302
906
  X = BO->getLHS();
12303
906
  D = BO->getRHS();
12304
12305
906
  auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12306
906
  if (!Cond) {
12307
2
    ErrorInfo.Error = ErrorTy::NotABinaryOp;
12308
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12309
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12310
2
    return false;
12311
2
  }
12312
904
  if (Cond->getOpcode() != BO_EQ) {
12313
2
    ErrorInfo.Error = ErrorTy::NotEQ;
12314
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12315
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12316
2
    return false;
12317
2
  }
12318
12319
902
  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12320
612
    E = Cond->getRHS();
12321
612
  } else 
if (290
checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())290
) {
12322
288
    E = Cond->getLHS();
12323
288
  } else {
12324
2
    ErrorInfo.Error = ErrorTy::InvalidComparison;
12325
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12326
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12327
2
    return false;
12328
2
  }
12329
12330
900
  C = Cond;
12331
12332
900
  if (!S->getElse()) {
12333
2
    ErrorInfo.Error = ErrorTy::NoElse;
12334
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12335
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12336
2
    return false;
12337
2
  }
12338
12339
898
  auto *Else = S->getElse();
12340
898
  if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
12341
586
    if (CS->body_empty()) {
12342
2
      ErrorInfo.Error = ErrorTy::NoStmt;
12343
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12344
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12345
2
      return false;
12346
2
    }
12347
584
    if (CS->size() > 1) {
12348
2
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12349
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12350
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12351
2
      return false;
12352
2
    }
12353
582
    Else = CS->body_front();
12354
582
  }
12355
12356
894
  auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12357
894
  if (!ElseBO) {
12358
2
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12359
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12360
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12361
2
    return false;
12362
2
  }
12363
892
  if (ElseBO->getOpcode() != BO_Assign) {
12364
2
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12365
2
    ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12366
2
    ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12367
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12368
2
    return false;
12369
2
  }
12370
12371
890
  if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12372
2
    ErrorInfo.Error = ErrorTy::InvalidAssignment;
12373
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12374
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12375
2
        ElseBO->getRHS()->getSourceRange();
12376
2
    return false;
12377
2
  }
12378
12379
888
  V = ElseBO->getLHS();
12380
12381
888
  return checkType(ErrorInfo);
12382
890
}
12383
12384
bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
12385
1.88k
                                                    ErrorInfoTy &ErrorInfo) {
12386
  // We don't check here as they should be already done before call this
12387
  // function.
12388
1.88k
  auto *CS = cast<CompoundStmt>(S);
12389
1.88k
  assert(CS->size() == 2 && "CompoundStmt size is not expected");
12390
1.88k
  auto *S1 = cast<BinaryOperator>(CS->body_front());
12391
1.88k
  auto *S2 = cast<IfStmt>(CS->body_back());
12392
1.88k
  assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
12393
12394
1.88k
  if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12395
2
    ErrorInfo.Error = ErrorTy::InvalidCondition;
12396
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12397
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12398
2
    return false;
12399
2
  }
12400
12401
1.88k
  R = S1->getLHS();
12402
12403
1.88k
  auto *Then = S2->getThen();
12404
1.88k
  if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12405
1.17k
    if (ThenCS->body_empty()) {
12406
2
      ErrorInfo.Error = ErrorTy::NoStmt;
12407
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12408
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12409
2
      return false;
12410
2
    }
12411
1.17k
    if (ThenCS->size() > 1) {
12412
2
      ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12413
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12414
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12415
2
      return false;
12416
2
    }
12417
1.17k
    Then = ThenCS->body_front();
12418
1.17k
  }
12419
12420
1.88k
  auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12421
1.88k
  if (!ThenBO) {
12422
2
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12423
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12424
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12425
2
    return false;
12426
2
  }
12427
1.87k
  if (ThenBO->getOpcode() != BO_Assign) {
12428
2
    ErrorInfo.Error = ErrorTy::NotAnAssignment;
12429
2
    ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12430
2
    ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12431
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12432
2
    return false;
12433
2
  }
12434
12435
1.87k
  X = ThenBO->getLHS();
12436
1.87k
  D = ThenBO->getRHS();
12437
12438
1.87k
  auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12439
1.87k
  if (BO->getOpcode() != BO_EQ) {
12440
2
    ErrorInfo.Error = ErrorTy::NotEQ;
12441
2
    ErrorInfo.ErrorLoc = BO->getExprLoc();
12442
2
    ErrorInfo.NoteLoc = BO->getOperatorLoc();
12443
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12444
2
    return false;
12445
2
  }
12446
12447
1.87k
  C = BO;
12448
12449
1.87k
  if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
12450
1.29k
    E = BO->getRHS();
12451
1.29k
  } else 
if (578
checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())578
) {
12452
576
    E = BO->getLHS();
12453
576
  } else {
12454
2
    ErrorInfo.Error = ErrorTy::InvalidComparison;
12455
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12456
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12457
2
    return false;
12458
2
  }
12459
12460
1.87k
  if (S2->getElse()) {
12461
898
    IsFailOnly = true;
12462
12463
898
    auto *Else = S2->getElse();
12464
898
    if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12465
586
      if (ElseCS->body_empty()) {
12466
2
        ErrorInfo.Error = ErrorTy::NoStmt;
12467
2
        ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12468
2
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12469
2
        return false;
12470
2
      }
12471
584
      if (ElseCS->size() > 1) {
12472
2
        ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12473
2
        ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12474
2
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12475
2
        return false;
12476
2
      }
12477
582
      Else = ElseCS->body_front();
12478
582
    }
12479
12480
894
    auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12481
894
    if (!ElseBO) {
12482
2
      ErrorInfo.Error = ErrorTy::NotAnAssignment;
12483
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12484
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12485
2
      return false;
12486
2
    }
12487
892
    if (ElseBO->getOpcode() != BO_Assign) {
12488
2
      ErrorInfo.Error = ErrorTy::NotAnAssignment;
12489
2
      ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12490
2
      ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12491
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12492
2
      return false;
12493
2
    }
12494
890
    if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12495
2
      ErrorInfo.Error = ErrorTy::InvalidAssignment;
12496
2
      ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12497
2
      ErrorInfo.NoteLoc = X->getExprLoc();
12498
2
      ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12499
2
      ErrorInfo.NoteRange = X->getSourceRange();
12500
2
      return false;
12501
2
    }
12502
12503
888
    V = ElseBO->getLHS();
12504
888
  }
12505
12506
1.86k
  return checkType(ErrorInfo);
12507
1.87k
}
12508
12509
bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
12510
10.1k
                                                  ErrorInfoTy &ErrorInfo) {
12511
  // if(x == e) { x = d; } else { v = x; }
12512
10.1k
  if (auto *IS = dyn_cast<IfStmt>(S))
12513
602
    return checkForm3(IS, ErrorInfo);
12514
12515
9.58k
  auto *CS = dyn_cast<CompoundStmt>(S);
12516
9.58k
  if (!CS) {
12517
2
    ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12518
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12519
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12520
2
    return false;
12521
2
  }
12522
9.58k
  if (CS->body_empty()) {
12523
2
    ErrorInfo.Error = ErrorTy::NoStmt;
12524
2
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12525
2
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12526
2
    return false;
12527
2
  }
12528
12529
  // { if(x == e) { x = d; } else { v = x; } }
12530
9.58k
  if (CS->size() == 1) {
12531
314
    auto *IS = dyn_cast<IfStmt>(CS->body_front());
12532
314
    if (!IS) {
12533
2
      ErrorInfo.Error = ErrorTy::NotIfStmt;
12534
2
      ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
12535
2
      ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12536
2
          CS->body_front()->getSourceRange();
12537
2
      return false;
12538
2
    }
12539
12540
312
    return checkForm3(IS, ErrorInfo);
12541
9.26k
  } else if (CS->size() == 2) {
12542
9.26k
    auto *S1 = CS->body_front();
12543
9.26k
    auto *S2 = CS->body_back();
12544
12545
9.26k
    Stmt *UpdateStmt = nullptr;
12546
9.26k
    Stmt *CondUpdateStmt = nullptr;
12547
9.26k
    Stmt *CondExprStmt = nullptr;
12548
12549
9.26k
    if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
12550
      // It could be one of the following cases:
12551
      // { v = x; cond-update-stmt }
12552
      // { v = x; cond-expr-stmt }
12553
      // { cond-expr-stmt; v = x; }
12554
      // form 45
12555
6.59k
      if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12556
6.59k
          
isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())4.71k
) {
12557
        // check if form 45
12558
2.82k
        if (isa<IfStmt>(S2))
12559
1.88k
          return checkForm45(CS, ErrorInfo);
12560
        // { cond-expr-stmt; v = x; }
12561
936
        CondExprStmt = S1;
12562
936
        UpdateStmt = S2;
12563
3.77k
      } else {
12564
3.77k
        IsPostfixUpdate = true;
12565
3.77k
        UpdateStmt = S1;
12566
3.77k
        if (isa<IfStmt>(S2)) {
12567
          // { v = x; cond-update-stmt }
12568
2.83k
          CondUpdateStmt = S2;
12569
2.83k
        } else {
12570
          // { v = x; cond-expr-stmt }
12571
938
          CondExprStmt = S2;
12572
938
        }
12573
3.77k
      }
12574
6.59k
    } else {
12575
      // { cond-update-stmt v = x; }
12576
2.66k
      UpdateStmt = S2;
12577
2.66k
      CondUpdateStmt = S1;
12578
2.66k
    }
12579
12580
7.38k
    auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
12581
5.50k
      auto *IS = dyn_cast<IfStmt>(CUS);
12582
5.50k
      if (!IS) {
12583
0
        ErrorInfo.Error = ErrorTy::NotIfStmt;
12584
0
        ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12585
0
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12586
0
        return false;
12587
0
      }
12588
12589
5.50k
      return checkCondUpdateStmt(IS, ErrorInfo);
12590
5.50k
    };
12591
12592
    // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12593
7.38k
    auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
12594
7.37k
      auto *BO = dyn_cast<BinaryOperator>(US);
12595
7.37k
      if (!BO) {
12596
0
        ErrorInfo.Error = ErrorTy::NotAnAssignment;
12597
0
        ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12598
0
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12599
0
        return false;
12600
0
      }
12601
7.37k
      if (BO->getOpcode() != BO_Assign) {
12602
4
        ErrorInfo.Error = ErrorTy::NotAnAssignment;
12603
4
        ErrorInfo.ErrorLoc = BO->getExprLoc();
12604
4
        ErrorInfo.NoteLoc = BO->getOperatorLoc();
12605
4
        ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12606
4
        return false;
12607
4
      }
12608
7.37k
      if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12609
4
        ErrorInfo.Error = ErrorTy::InvalidAssignment;
12610
4
        ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12611
4
        ErrorInfo.NoteLoc = this->X->getExprLoc();
12612
4
        ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12613
4
        ErrorInfo.NoteRange = this->X->getSourceRange();
12614
4
        return false;
12615
4
      }
12616
12617
7.37k
      this->V = BO->getLHS();
12618
12619
7.37k
      return true;
12620
7.37k
    };
12621
12622
7.38k
    if (CondUpdateStmt && 
!CheckCondUpdateStmt(CondUpdateStmt)5.50k
)
12623
0
      return false;
12624
7.38k
    if (CondExprStmt && 
!checkCondExprStmt(CondExprStmt, ErrorInfo)1.87k
)
12625
2
      return false;
12626
7.37k
    if (!CheckUpdateStmt(UpdateStmt))
12627
8
      return false;
12628
7.37k
  } else {
12629
0
    ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12630
0
    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12631
0
    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12632
0
    return false;
12633
0
  }
12634
12635
7.37k
  return checkType(ErrorInfo);
12636
9.58k
}
12637
} // namespace
12638
12639
StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
12640
                                            Stmt *AStmt,
12641
                                            SourceLocation StartLoc,
12642
20.4k
                                            SourceLocation EndLoc) {
12643
  // Register location of the first atomic directive.
12644
20.4k
  DSAStack->addAtomicDirectiveLoc(StartLoc);
12645
20.4k
  if (!AStmt)
12646
0
    return StmtError();
12647
12648
  // 1.2.2 OpenMP Language Terminology
12649
  // Structured block - An executable statement with a single entry at the
12650
  // top and a single exit at the bottom.
12651
  // The point of exit cannot be a branch out of the structured block.
12652
  // longjmp() and throw() must not violate the entry/exit criteria.
12653
20.4k
  OpenMPClauseKind AtomicKind = OMPC_unknown;
12654
20.4k
  SourceLocation AtomicKindLoc;
12655
20.4k
  OpenMPClauseKind MemOrderKind = OMPC_unknown;
12656
20.4k
  SourceLocation MemOrderLoc;
12657
20.4k
  bool MutexClauseEncountered = false;
12658
20.4k
  llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12659
40.6k
  for (const OMPClause *C : Clauses) {
12660
40.6k
    switch (C->getClauseKind()) {
12661
631
    case OMPC_read:
12662
1.22k
    case OMPC_write:
12663
1.97k
    case OMPC_update:
12664
1.97k
      MutexClauseEncountered = true;
12665
1.97k
      [[fallthrough]];
12666
14.5k
    case OMPC_capture:
12667
28.2k
    case OMPC_compare: {
12668
28.2k
      if (AtomicKind != OMPC_unknown && 
MutexClauseEncountered10.2k
) {
12669
84
        Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12670
84
            << SourceRange(C->getBeginLoc(), C->getEndLoc());
12671
84
        Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12672
84
            << getOpenMPClauseName(AtomicKind);
12673
28.1k
      } else {
12674
28.1k
        AtomicKind = C->getClauseKind();
12675
28.1k
        AtomicKindLoc = C->getBeginLoc();
12676
28.1k
        if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12677
0
          Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12678
0
              << SourceRange(C->getBeginLoc(), C->getEndLoc());
12679
0
          Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12680
0
              << getOpenMPClauseName(AtomicKind);
12681
0
        }
12682
28.1k
      }
12683
28.2k
      break;
12684
14.5k
    }
12685
2.59k
    case OMPC_seq_cst:
12686
4.94k
    case OMPC_acq_rel:
12687
7.31k
    case OMPC_acquire:
12688
9.73k
    case OMPC_release:
12689
12.1k
    case OMPC_relaxed: {
12690
12.1k
      if (MemOrderKind != OMPC_unknown) {
12691
48
        Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12692
48
            << getOpenMPDirectiveName(OMPD_atomic) << 0
12693
48
            << SourceRange(C->getBeginLoc(), C->getEndLoc());
12694
48
        Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12695
48
            << getOpenMPClauseName(MemOrderKind);
12696
12.1k
      } else {
12697
12.1k
        MemOrderKind = C->getClauseKind();
12698
12.1k
        MemOrderLoc = C->getBeginLoc();
12699
12.1k
      }
12700
12.1k
      break;
12701
9.73k
    }
12702
    // The following clauses are allowed, but we don't need to do anything here.
12703
228
    case OMPC_hint:
12704
228
      break;
12705
0
    default:
12706
0
      llvm_unreachable("unknown clause is encountered");
12707
40.6k
    }
12708
40.6k
  }
12709
20.4k
  bool IsCompareCapture = false;
12710
20.4k
  if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12711
20.4k
      
EncounteredAtomicKinds.contains(OMPC_capture)13.7k
) {
12712
10.1k
    IsCompareCapture = true;
12713
10.1k
    AtomicKind = OMPC_compare;
12714
10.1k
  }
12715
  // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12716
  // If atomic-clause is read then memory-order-clause must not be acq_rel or
12717
  // release.
12718
  // If atomic-clause is write then memory-order-clause must not be acq_rel or
12719
  // acquire.
12720
  // If atomic-clause is update or not present then memory-order-clause must not
12721
  // be acq_rel or acquire.
12722
20.4k
  if ((AtomicKind == OMPC_read &&
12723
20.4k
       
(589
MemOrderKind == OMPC_acq_rel589
||
MemOrderKind == OMPC_release581
)) ||
12724
20.4k
      
(20.4k
(20.4k
AtomicKind == OMPC_write20.4k
||
AtomicKind == OMPC_update19.8k
||
12725
20.4k
        
AtomicKind == OMPC_unknown19.0k
) &&
12726
20.4k
       
(3.76k
MemOrderKind == OMPC_acq_rel3.76k
||
MemOrderKind == OMPC_acquire3.75k
))) {
12727
52
    SourceLocation Loc = AtomicKindLoc;
12728
52
    if (AtomicKind == OMPC_unknown)
12729
16
      Loc = StartLoc;
12730
52
    Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12731
52
        << getOpenMPClauseName(AtomicKind)
12732
52
        << (AtomicKind == OMPC_unknown ? 
116
:
036
)
12733
52
        << getOpenMPClauseName(MemOrderKind);
12734
52
    Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12735
52
        << getOpenMPClauseName(MemOrderKind);
12736
52
  }
12737
12738
20.4k
  Stmt *Body = AStmt;
12739
20.4k
  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12740
32
    Body = EWC->getSubExpr();
12741
12742
20.4k
  Expr *X = nullptr;
12743
20.4k
  Expr *V = nullptr;
12744
20.4k
  Expr *E = nullptr;
12745
20.4k
  Expr *UE = nullptr;
12746
20.4k
  Expr *D = nullptr;
12747
20.4k
  Expr *CE = nullptr;
12748
20.4k
  Expr *R = nullptr;
12749
20.4k
  bool IsXLHSInRHSPart = false;
12750
20.4k
  bool IsPostfixUpdate = false;
12751
20.4k
  bool IsFailOnly = false;
12752
  // OpenMP [2.12.6, atomic Construct]
12753
  // In the next expressions:
12754
  // * x and v (as applicable) are both l-value expressions with scalar type.
12755
  // * During the execution of an atomic region, multiple syntactic
12756
  // occurrences of x must designate the same storage location.
12757
  // * Neither of v and expr (as applicable) may access the storage location
12758
  // designated by x.
12759
  // * Neither of x and expr (as applicable) may access the storage location
12760
  // designated by v.
12761
  // * expr is an expression with scalar type.
12762
  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12763
  // * binop, binop=, ++, and -- are not overloaded operators.
12764
  // * The expression x binop expr must be numerically equivalent to x binop
12765
  // (expr). This requirement is satisfied if the operators in expr have
12766
  // precedence greater than binop, or by using parentheses around expr or
12767
  // subexpressions of expr.
12768
  // * The expression expr binop x must be numerically equivalent to (expr)
12769
  // binop x. This requirement is satisfied if the operators in expr have
12770
  // precedence equal to or greater than binop, or by using parentheses around
12771
  // expr or subexpressions of expr.
12772
  // * For forms that allow multiple occurrences of x, the number of times
12773
  // that x is evaluated is unspecified.
12774
20.4k
  if (AtomicKind == OMPC_read) {
12775
589
    enum {
12776
589
      NotAnExpression,
12777
589
      NotAnAssignmentOp,
12778
589
      NotAScalarType,
12779
589
      NotAnLValue,
12780
589
      NoError
12781
589
    } ErrorFound = NoError;
12782
589
    SourceLocation ErrorLoc, NoteLoc;
12783
589
    SourceRange ErrorRange, NoteRange;
12784
    // If clause is read:
12785
    //  v = x;
12786
589
    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12787
559
      const auto *AtomicBinOp =
12788
559
          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12789
559
      if (AtomicBinOp && 
AtomicBinOp->getOpcode() == BO_Assign523
) {
12790
499
        X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12791
499
        V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12792
499
        if ((X->isInstantiationDependent() || 
X->getType()->isScalarType()417
) &&
12793
499
            
(493
V->isInstantiationDependent()493
||
V->getType()->isScalarType()405
)) {
12794
493
          if (!X->isLValue() || 
!V->isLValue()475
) {
12795
18
            const Expr *NotLValueExpr = X->isLValue() ? 
V0
: X;
12796
18
            ErrorFound = NotAnLValue;
12797
18
            ErrorLoc = AtomicBinOp->getExprLoc();
12798
18
            ErrorRange = AtomicBinOp->getSourceRange();
12799
18
            NoteLoc = NotLValueExpr->getExprLoc();
12800
18
            NoteRange = NotLValueExpr->getSourceRange();
12801
18
          }
12802
493
        } else 
if (6
!X->isInstantiationDependent()6
||
12803
6
                   
!V->isInstantiationDependent()0
) {
12804
6
          const Expr *NotScalarExpr =
12805
6
              (X->isInstantiationDependent() || X->getType()->isScalarType())
12806
6
                  ? 
V0
12807
6
                  : X;
12808
6
          ErrorFound = NotAScalarType;
12809
6
          ErrorLoc = AtomicBinOp->getExprLoc();
12810
6
          ErrorRange = AtomicBinOp->getSourceRange();
12811
6
          NoteLoc = NotScalarExpr->getExprLoc();
12812
6
          NoteRange = NotScalarExpr->getSourceRange();
12813
6
        }
12814
499
      } else 
if (60
!AtomicBody->isInstantiationDependent()60
) {
12815
54
        ErrorFound = NotAnAssignmentOp;
12816
54
        ErrorLoc = AtomicBody->getExprLoc();
12817
54
        ErrorRange = AtomicBody->getSourceRange();
12818
54
        NoteLoc = AtomicBinOp ? 
AtomicBinOp->getOperatorLoc()18
12819
54
                              : 
AtomicBody->getExprLoc()36
;
12820
54
        NoteRange = AtomicBinOp ? 
AtomicBinOp->getSourceRange()18
12821
54
                                : 
AtomicBody->getSourceRange()36
;
12822
54
      }
12823
559
    } else {
12824
30
      ErrorFound = NotAnExpression;
12825
30
      NoteLoc = ErrorLoc = Body->getBeginLoc();
12826
30
      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12827
30
    }
12828
589
    if (ErrorFound != NoError) {
12829
108
      Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12830
108
          << ErrorRange;
12831
108
      Diag(NoteLoc, diag::note_omp_atomic_read_write)
12832
108
          << ErrorFound << NoteRange;
12833
108
      return StmtError();
12834
108
    }
12835
481
    if (CurContext->isDependentContext())
12836
88
      V = X = nullptr;
12837
19.8k
  } else if (AtomicKind == OMPC_write) {
12838
576
    enum {
12839
576
      NotAnExpression,
12840
576
      NotAnAssignmentOp,
12841
576
      NotAScalarType,
12842
576
      NotAnLValue,
12843
576
      NoError
12844
576
    } ErrorFound = NoError;
12845
576
    SourceLocation ErrorLoc, NoteLoc;
12846
576
    SourceRange ErrorRange, NoteRange;
12847
    // If clause is write:
12848
    //  x = expr;
12849
576
    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12850
546
      const auto *AtomicBinOp =
12851
546
          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12852
546
      if (AtomicBinOp && 
AtomicBinOp->getOpcode() == BO_Assign528
) {
12853
504
        X = AtomicBinOp->getLHS();
12854
504
        E = AtomicBinOp->getRHS();
12855
504
        if ((X->isInstantiationDependent() || 
X->getType()->isScalarType()422
) &&
12856
504
            
(498
E->isInstantiationDependent()498
||
E->getType()->isScalarType()422
)) {
12857
498
          if (!X->isLValue()) {
12858
0
            ErrorFound = NotAnLValue;
12859
0
            ErrorLoc = AtomicBinOp->getExprLoc();
12860
0
            ErrorRange = AtomicBinOp->getSourceRange();
12861
0
            NoteLoc = X->getExprLoc();
12862
0
            NoteRange = X->getSourceRange();
12863
0
          }
12864
498
        } else 
if (6
!X->isInstantiationDependent()6
||
12865
6
                   
!E->isInstantiationDependent()0
) {
12866
6
          const Expr *NotScalarExpr =
12867
6
              (X->isInstantiationDependent() || X->getType()->isScalarType())
12868
6
                  ? 
E0
12869
6
                  : X;
12870
6
          ErrorFound = NotAScalarType;
12871
6
          ErrorLoc = AtomicBinOp->getExprLoc();
12872
6
          ErrorRange = AtomicBinOp->getSourceRange();
12873
6
          NoteLoc = NotScalarExpr->getExprLoc();
12874
6
          NoteRange = NotScalarExpr->getSourceRange();
12875
6
        }
12876
504
      } else 
if (42
!AtomicBody->isInstantiationDependent()42
) {
12877
36
        ErrorFound = NotAnAssignmentOp;
12878
36
        ErrorLoc = AtomicBody->getExprLoc();
12879
36
        ErrorRange = AtomicBody->getSourceRange();
12880
36
        NoteLoc = AtomicBinOp ? 
AtomicBinOp->getOperatorLoc()18
12881
36
                              : 
AtomicBody->getExprLoc()18
;
12882
36
        NoteRange = AtomicBinOp ? 
AtomicBinOp->getSourceRange()18
12883
36
                                : 
AtomicBody->getSourceRange()18
;
12884
36
      }
12885
546
    } else {
12886
30
      ErrorFound = NotAnExpression;
12887
30
      NoteLoc = ErrorLoc = Body->getBeginLoc();
12888
30
      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12889
30
    }
12890
576
    if (ErrorFound != NoError) {
12891
72
      Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12892
72
          << ErrorRange;
12893
72
      Diag(NoteLoc, diag::note_omp_atomic_read_write)
12894
72
          << ErrorFound << NoteRange;
12895
72
      return StmtError();
12896
72
    }
12897
504
    if (CurContext->isDependentContext())
12898
88
      E = X = nullptr;
12899
19.2k
  } else if (AtomicKind == OMPC_update || 
AtomicKind == OMPC_unknown18.5k
) {
12900
    // If clause is update:
12901
    //  x++;
12902
    //  x--;
12903
    //  ++x;
12904
    //  --x;
12905
    //  x binop= expr;
12906
    //  x = x binop expr;
12907
    //  x = expr binop x;
12908
3.19k
    OpenMPAtomicUpdateChecker Checker(*this);
12909
3.19k
    if (Checker.checkStatement(
12910
3.19k
            Body,
12911
3.19k
            (AtomicKind == OMPC_update)
12912
3.19k
                ? 
diag::err_omp_atomic_update_not_expression_statement745
12913
3.19k
                : 
diag::err_omp_atomic_not_expression_statement2.44k
,
12914
3.19k
            diag::note_omp_atomic_update))
12915
1.06k
      return StmtError();
12916
2.12k
    if (!CurContext->isDependentContext()) {
12917
1.56k
      E = Checker.getExpr();
12918
1.56k
      X = Checker.getX();
12919
1.56k
      UE = Checker.getUpdateExpr();
12920
1.56k
      IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12921
1.56k
    }
12922
16.0k
  } else if (AtomicKind == OMPC_capture) {
12923
2.33k
    enum {
12924
2.33k
      NotAnAssignmentOp,
12925
2.33k
      NotACompoundStatement,
12926
2.33k
      NotTwoSubstatements,
12927
2.33k
      NotASpecificExpression,
12928
2.33k
      NoError
12929
2.33k
    } ErrorFound = NoError;
12930
2.33k
    SourceLocation ErrorLoc, NoteLoc;
12931
2.33k
    SourceRange ErrorRange, NoteRange;
12932
2.33k
    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12933
      // If clause is a capture:
12934
      //  v = x++;
12935
      //  v = x--;
12936
      //  v = ++x;
12937
      //  v = --x;
12938
      //  v = x binop= expr;
12939
      //  v = x = x binop expr;
12940
      //  v = x = expr binop x;
12941
1.13k
      const auto *AtomicBinOp =
12942
1.13k
          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12943
1.13k
      if (AtomicBinOp && 
AtomicBinOp->getOpcode() == BO_Assign1.11k
) {
12944
1.11k
        V = AtomicBinOp->getLHS();
12945
1.11k
        Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12946
1.11k
        OpenMPAtomicUpdateChecker Checker(*this);
12947
1.11k
        if (Checker.checkStatement(
12948
1.11k
                Body, diag::err_omp_atomic_capture_not_expression_statement,
12949
1.11k
                diag::note_omp_atomic_update))
12950
162
          return StmtError();
12951
954
        E = Checker.getExpr();
12952
954
        X = Checker.getX();
12953
954
        UE = Checker.getUpdateExpr();
12954
954
        IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12955
954
        IsPostfixUpdate = Checker.isPostfixUpdate();
12956
954
      } else 
if (18
!AtomicBody->isInstantiationDependent()18
) {
12957
18
        ErrorLoc = AtomicBody->getExprLoc();
12958
18
        ErrorRange = AtomicBody->getSourceRange();
12959
18
        NoteLoc = AtomicBinOp ? 
AtomicBinOp->getOperatorLoc()0
12960
18
                              : AtomicBody->getExprLoc();
12961
18
        NoteRange = AtomicBinOp ? 
AtomicBinOp->getSourceRange()0
12962
18
                                : AtomicBody->getSourceRange();
12963
18
        ErrorFound = NotAnAssignmentOp;
12964
18
      }
12965
972
      if (ErrorFound != NoError) {
12966
18
        Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12967
18
            << ErrorRange;
12968
18
        Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12969
18
        return StmtError();
12970
18
      }
12971
954
      if (CurContext->isDependentContext())
12972
218
        UE = V = E = X = nullptr;
12973
1.19k
    } else {
12974
      // If clause is a capture:
12975
      //  { v = x; x = expr; }
12976
      //  { v = x; x++; }
12977
      //  { v = x; x--; }
12978
      //  { v = x; ++x; }
12979
      //  { v = x; --x; }
12980
      //  { v = x; x binop= expr; }
12981
      //  { v = x; x = x binop expr; }
12982
      //  { v = x; x = expr binop x; }
12983
      //  { x++; v = x; }
12984
      //  { x--; v = x; }
12985
      //  { ++x; v = x; }
12986
      //  { --x; v = x; }
12987
      //  { x binop= expr; v = x; }
12988
      //  { x = x binop expr; v = x; }
12989
      //  { x = expr binop x; v = x; }
12990
1.19k
      if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12991
        // Check that this is { expr1; expr2; }
12992
1.18k
        if (CS->size() == 2) {
12993
1.14k
          Stmt *First = CS->body_front();
12994
1.14k
          Stmt *Second = CS->body_back();
12995
1.14k
          if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
12996
0
            First = EWC->getSubExpr()->IgnoreParenImpCasts();
12997
1.14k
          if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12998
0
            Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12999
          // Need to find what subexpression is 'v' and what is 'x'.
13000
1.14k
          OpenMPAtomicUpdateChecker Checker(*this);
13001
1.14k
          bool IsUpdateExprFound = !Checker.checkStatement(Second);
13002
1.14k
          BinaryOperator *BinOp = nullptr;
13003
1.14k
          if (IsUpdateExprFound) {
13004
640
            BinOp = dyn_cast<BinaryOperator>(First);
13005
640
            IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
13006
640
          }
13007
1.14k
          if (IsUpdateExprFound && 
!CurContext->isDependentContext()640
) {
13008
            //  { v = x; x++; }
13009
            //  { v = x; x--; }
13010
            //  { v = x; ++x; }
13011
            //  { v = x; --x; }
13012
            //  { v = x; x binop= expr; }
13013
            //  { v = x; x = x binop expr; }
13014
            //  { v = x; x = expr binop x; }
13015
            // Check that the first expression has form v = x.
13016
494
            Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
13017
494
            llvm::FoldingSetNodeID XId, PossibleXId;
13018
494
            Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
13019
494
            PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
13020
494
            IsUpdateExprFound = XId == PossibleXId;
13021
494
            if (IsUpdateExprFound) {
13022
494
              V = BinOp->getLHS();
13023
494
              X = Checker.getX();
13024
494
              E = Checker.getExpr();
13025
494
              UE = Checker.getUpdateExpr();
13026
494
              IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13027
494
              IsPostfixUpdate = true;
13028
494
            }
13029
494
          }
13030
1.14k
          if (!IsUpdateExprFound) {
13031
505
            IsUpdateExprFound = !Checker.checkStatement(First);
13032
505
            BinOp = nullptr;
13033
505
            if (IsUpdateExprFound) {
13034
400
              BinOp = dyn_cast<BinaryOperator>(Second);
13035
400
              IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
13036
400
            }
13037
505
            if (IsUpdateExprFound && 
!CurContext->isDependentContext()400
) {
13038
              //  { x++; v = x; }
13039
              //  { x--; v = x; }
13040
              //  { ++x; v = x; }
13041
              //  { --x; v = x; }
13042
              //  { x binop= expr; v = x; }
13043
              //  { x = x binop expr; v = x; }
13044
              //  { x = expr binop x; v = x; }
13045
              // Check that the second expression has form v = x.
13046
328
              Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
13047
328
              llvm::FoldingSetNodeID XId, PossibleXId;
13048
328
              Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
13049
328
              PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
13050
328
              IsUpdateExprFound = XId == PossibleXId;
13051
328
              if (IsUpdateExprFound) {
13052
328
                V = BinOp->getLHS();
13053
328
                X = Checker.getX();
13054
328
                E = Checker.getExpr();
13055
328
                UE = Checker.getUpdateExpr();
13056
328
                IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13057
328
                IsPostfixUpdate = false;
13058
328
              }
13059
328
            }
13060
505
          }
13061
1.14k
          if (!IsUpdateExprFound) {
13062
            //  { v = x; x = expr; }
13063
105
            auto *FirstExpr = dyn_cast<Expr>(First);
13064
105
            auto *SecondExpr = dyn_cast<Expr>(Second);
13065
105
            if (!FirstExpr || !SecondExpr ||
13066
105
                !(FirstExpr->isInstantiationDependent() ||
13067
105
                  
SecondExpr->isInstantiationDependent()81
)) {
13068
80
              auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
13069
80
              if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
13070
0
                ErrorFound = NotAnAssignmentOp;
13071
0
                NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
13072
0
                                                : First->getBeginLoc();
13073
0
                NoteRange = ErrorRange = FirstBinOp
13074
0
                                             ? FirstBinOp->getSourceRange()
13075
0
                                             : SourceRange(ErrorLoc, ErrorLoc);
13076
80
              } else {
13077
80
                auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
13078
80
                if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
13079
0
                  ErrorFound = NotAnAssignmentOp;
13080
0
                  NoteLoc = ErrorLoc = SecondBinOp
13081
0
                                           ? SecondBinOp->getOperatorLoc()
13082
0
                                           : Second->getBeginLoc();
13083
0
                  NoteRange = ErrorRange =
13084
0
                      SecondBinOp ? SecondBinOp->getSourceRange()
13085
0
                                  : SourceRange(ErrorLoc, ErrorLoc);
13086
80
                } else {
13087
80
                  Expr *PossibleXRHSInFirst =
13088
80
                      FirstBinOp->getRHS()->IgnoreParenImpCasts();
13089
80
                  Expr *PossibleXLHSInSecond =
13090
80
                      SecondBinOp->getLHS()->IgnoreParenImpCasts();
13091
80
                  llvm::FoldingSetNodeID X1Id, X2Id;
13092
80
                  PossibleXRHSInFirst->Profile(X1Id, Context,
13093
80
                                               /*Canonical=*/true);
13094
80
                  PossibleXLHSInSecond->Profile(X2Id, Context,
13095
80
                                                /*Canonical=*/true);
13096
80
                  IsUpdateExprFound = X1Id == X2Id;
13097
80
                  if (IsUpdateExprFound) {
13098
44
                    V = FirstBinOp->getLHS();
13099
44
                    X = SecondBinOp->getLHS();
13100
44
                    E = SecondBinOp->getRHS();
13101
44
                    UE = nullptr;
13102
44
                    IsXLHSInRHSPart = false;
13103
44
                    IsPostfixUpdate = true;
13104
44
                  } else {
13105
36
                    ErrorFound = NotASpecificExpression;
13106
36
                    ErrorLoc = FirstBinOp->getExprLoc();
13107
36
                    ErrorRange = FirstBinOp->getSourceRange();
13108
36
                    NoteLoc = SecondBinOp->getLHS()->getExprLoc();
13109
36
                    NoteRange = SecondBinOp->getRHS()->getSourceRange();
13110
36
                  }
13111
80
                }
13112
80
              }
13113
80
            }
13114
105
          }
13115
1.14k
        } else {
13116
36
          NoteLoc = ErrorLoc = Body->getBeginLoc();
13117
36
          NoteRange = ErrorRange =
13118
36
              SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
13119
36
          ErrorFound = NotTwoSubstatements;
13120
36
        }
13121
1.18k
      } else {
13122
18
        NoteLoc = ErrorLoc = Body->getBeginLoc();
13123
18
        NoteRange = ErrorRange =
13124
18
            SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
13125
18
        ErrorFound = NotACompoundStatement;
13126
18
      }
13127
1.19k
    }
13128
2.15k
    if (ErrorFound != NoError) {
13129
90
      Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
13130
90
          << ErrorRange;
13131
90
      Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13132
90
      return StmtError();
13133
90
    }
13134
2.06k
    if (CurContext->isDependentContext())
13135
460
      UE = V = E = X = nullptr;
13136
13.7k
  } else if (AtomicKind == OMPC_compare) {
13137
13.7k
    if (IsCompareCapture) {
13138
10.1k
      OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
13139
10.1k
      OpenMPAtomicCompareCaptureChecker Checker(*this);
13140
10.1k
      if (!Checker.checkStmt(Body, ErrorInfo)) {
13141
68
        Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
13142
68
            << ErrorInfo.ErrorRange;
13143
68
        Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13144
68
            << ErrorInfo.Error << ErrorInfo.NoteRange;
13145
68
        return StmtError();
13146
68
      }
13147
10.1k
      X = Checker.getX();
13148
10.1k
      E = Checker.getE();
13149
10.1k
      D = Checker.getD();
13150
10.1k
      CE = Checker.getCond();
13151
10.1k
      V = Checker.getV();
13152
10.1k
      R = Checker.getR();
13153
      // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
13154
10.1k
      IsXLHSInRHSPart = Checker.isXBinopExpr();
13155
10.1k
      IsFailOnly = Checker.isFailOnly();
13156
10.1k
      IsPostfixUpdate = Checker.isPostfixUpdate();
13157
10.1k
    } else {
13158
3.54k
      OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
13159
3.54k
      OpenMPAtomicCompareChecker Checker(*this);
13160
3.54k
      if (!Checker.checkStmt(Body, ErrorInfo)) {
13161
28
        Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
13162
28
            << ErrorInfo.ErrorRange;
13163
28
        Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13164
28
          << ErrorInfo.Error << ErrorInfo.NoteRange;
13165
28
        return StmtError();
13166
28
      }
13167
3.51k
      X = Checker.getX();
13168
3.51k
      E = Checker.getE();
13169
3.51k
      D = Checker.getD();
13170
3.51k
      CE = Checker.getCond();
13171
      // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
13172
3.51k
      IsXLHSInRHSPart = Checker.isXBinopExpr();
13173
3.51k
    }
13174
13.7k
  }
13175
13176
18.8k
  setFunctionHasBranchProtectedScope();
13177
13178
18.8k
  return OMPAtomicDirective::Create(
13179
18.8k
      Context, StartLoc, EndLoc, Clauses, AStmt,
13180
18.8k
      {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
13181
20.4k
}
13182
13183
StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
13184
                                            Stmt *AStmt,
13185
                                            SourceLocation StartLoc,
13186
75.3k
                                            SourceLocation EndLoc) {
13187
75.3k
  if (!AStmt)
13188
2.17k
    return StmtError();
13189
13190
73.1k
  auto *CS = cast<CapturedStmt>(AStmt);
13191
  // 1.2.2 OpenMP Language Terminology
13192
  // Structured block - An executable statement with a single entry at the
13193
  // top and a single exit at the bottom.
13194
  // The point of exit cannot be a branch out of the structured block.
13195
  // longjmp() and throw() must not violate the entry/exit criteria.
13196
73.1k
  CS->getCapturedDecl()->setNothrow();
13197
73.1k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
13198
146k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel73.1k
) {
13199
73.1k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13200
    // 1.2.2 OpenMP Language Terminology
13201
    // Structured block - An executable statement with a single entry at the
13202
    // top and a single exit at the bottom.
13203
    // The point of exit cannot be a branch out of the structured block.
13204
    // longjmp() and throw() must not violate the entry/exit criteria.
13205
73.1k
    CS->getCapturedDecl()->setNothrow();
13206
73.1k
  }
13207
13208
  // OpenMP [2.16, Nesting of Regions]
13209
  // If specified, a teams construct must be contained within a target
13210
  // construct. That target construct must contain no statements or directives
13211
  // outside of the teams construct.
13212
73.1k
  if (DSAStack->hasInnerTeamsRegion()) {
13213
51.9k
    const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
13214
51.9k
    bool OMPTeamsFound = true;
13215
51.9k
    if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
13216
36
      auto I = CS->body_begin();
13217
36
      while (I != CS->body_end()) {
13218
36
        const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
13219
36
        if (!OED || 
!isOpenMPTeamsDirective(OED->getDirectiveKind())18
||
13220
36
            
OMPTeamsFound18
) {
13221
13222
36
          OMPTeamsFound = false;
13223
36
          break;
13224
36
        }
13225
0
        ++I;
13226
0
      }
13227
36
      assert(I != CS->body_end() && "Not found statement");
13228
36
      S = *I;
13229
51.8k
    } else {
13230
51.8k
      const auto *OED = dyn_cast<OMPExecutableDirective>(S);
13231
51.8k
      OMPTeamsFound = OED && 
isOpenMPTeamsDirective(OED->getDirectiveKind())51.8k
;
13232
51.8k
    }
13233
51.9k
    if (!OMPTeamsFound) {
13234
45
      Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
13235
45
      Diag(DSAStack->getInnerTeamsRegionLoc(),
13236
45
           diag::note_omp_nested_teams_construct_here);
13237
45
      Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
13238
45
          << isa<OMPExecutableDirective>(S);
13239
45
      return StmtError();
13240
45
    }
13241
51.9k
  }
13242
13243
73.1k
  setFunctionHasBranchProtectedScope();
13244
13245
73.1k
  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13246
73.1k
}
13247
13248
StmtResult
13249
Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
13250
                                         Stmt *AStmt, SourceLocation StartLoc,
13251
9.87k
                                         SourceLocation EndLoc) {
13252
9.87k
  if (!AStmt)
13253
36
    return StmtError();
13254
13255
9.84k
  auto *CS = cast<CapturedStmt>(AStmt);
13256
  // 1.2.2 OpenMP Language Terminology
13257
  // Structured block - An executable statement with a single entry at the
13258
  // top and a single exit at the bottom.
13259
  // The point of exit cannot be a branch out of the structured block.
13260
  // longjmp() and throw() must not violate the entry/exit criteria.
13261
9.84k
  CS->getCapturedDecl()->setNothrow();
13262
9.84k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
13263
29.5k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel19.6k
) {
13264
19.6k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13265
    // 1.2.2 OpenMP Language Terminology
13266
    // Structured block - An executable statement with a single entry at the
13267
    // top and a single exit at the bottom.
13268
    // The point of exit cannot be a branch out of the structured block.
13269
    // longjmp() and throw() must not violate the entry/exit criteria.
13270
19.6k
    CS->getCapturedDecl()->setNothrow();
13271
19.6k
  }
13272
13273
9.84k
  setFunctionHasBranchProtectedScope();
13274
13275
9.84k
  return OMPTargetParallelDirective::Create(
13276
9.84k
      Context, StartLoc, EndLoc, Clauses, AStmt,
13277
9.84k
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13278
9.87k
}
13279
13280
StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
13281
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13282
10.5k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13283
10.5k
  if (!AStmt)
13284
2
    return StmtError();
13285
13286
10.5k
  auto *CS = cast<CapturedStmt>(AStmt);
13287
  // 1.2.2 OpenMP Language Terminology
13288
  // Structured block - An executable statement with a single entry at the
13289
  // top and a single exit at the bottom.
13290
  // The point of exit cannot be a branch out of the structured block.
13291
  // longjmp() and throw() must not violate the entry/exit criteria.
13292
10.5k
  CS->getCapturedDecl()->setNothrow();
13293
10.5k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13294
31.5k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel21.0k
) {
13295
21.0k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13296
    // 1.2.2 OpenMP Language Terminology
13297
    // Structured block - An executable statement with a single entry at the
13298
    // top and a single exit at the bottom.
13299
    // The point of exit cannot be a branch out of the structured block.
13300
    // longjmp() and throw() must not violate the entry/exit criteria.
13301
21.0k
    CS->getCapturedDecl()->setNothrow();
13302
21.0k
  }
13303
13304
10.5k
  OMPLoopBasedDirective::HelperExprs B;
13305
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13306
  // define the nested loops number.
13307
10.5k
  unsigned NestedLoopCount =
13308
10.5k
      checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
13309
10.5k
                      getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
13310
10.5k
                      VarsWithImplicitDSA, B);
13311
10.5k
  if (NestedLoopCount == 0)
13312
314
    return StmtError();
13313
13314
10.2k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13315
10.2k
         "omp target parallel for loop exprs were not built");
13316
13317
10.2k
  if (!CurContext->isDependentContext()) {
13318
    // Finalize the clauses that need pre-built expressions for CodeGen.
13319
8.81k
    for (OMPClause *C : Clauses) {
13320
8.81k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
13321
227
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13322
227
                                     B.NumIterations, *this, CurScope,
13323
227
                                     DSAStack))
13324
0
          return StmtError();
13325
8.81k
    }
13326
7.57k
  }
13327
13328
10.2k
  setFunctionHasBranchProtectedScope();
13329
10.2k
  return OMPTargetParallelForDirective::Create(
13330
10.2k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13331
10.2k
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13332
10.2k
}
13333
13334
/// Check for existence of a map clause in the list of clauses.
13335
static bool hasClauses(ArrayRef<OMPClause *> Clauses,
13336
17.1k
                       const OpenMPClauseKind K) {
13337
17.1k
  return llvm::any_of(
13338
17.5k
      Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
13339
17.1k
}
13340
13341
template <typename... Params>
13342
static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
13343
10.5k
                       const Params... ClauseTypes) {
13344
10.5k
  return hasClauses(Clauses, K) || 
hasClauses(Clauses, ClauseTypes...)2.05k
;
13345
10.5k
}
SemaOpenMP.cpp:bool hasClauses<llvm::omp::Clause>(llvm::ArrayRef<clang::OMPClause*>, llvm::omp::Clause, llvm::omp::Clause const)
Line
Count
Source
13343
10.2k
                       const Params... ClauseTypes) {
13344
10.2k
  return hasClauses(Clauses, K) || 
hasClauses(Clauses, ClauseTypes...)1.92k
;
13345
10.2k
}
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)
Line
Count
Source
13343
218
                       const Params... ClauseTypes) {
13344
218
  return hasClauses(Clauses, K) || 
hasClauses(Clauses, ClauseTypes...)87
;
13345
218
}
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)
Line
Count
Source
13343
87
                       const Params... ClauseTypes) {
13344
87
  return hasClauses(Clauses, K) || 
hasClauses(Clauses, ClauseTypes...)42
;
13345
87
}
13346
13347
/// Check if the variables in the mapping clause are externally visible.
13348
3.67k
static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) {
13349
3.71k
  for (const OMPClause *C : Clauses) {
13350
3.71k
    if (auto *TC = dyn_cast<OMPToClause>(C))
13351
2.40k
      return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
13352
2.20k
        return !VD || 
!VD->hasAttr<OMPDeclareTargetDeclAttr>()2.17k
||
13353
2.20k
               
(15
VD->isExternallyVisible()15
&&
13354
15
                
VD->getVisibility() != HiddenVisibility8
);
13355
2.20k
      });
13356
1.30k
    else if (auto *FC = dyn_cast<OMPFromClause>(C))
13357
1.27k
      return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
13358
1.20k
        return !VD || 
!VD->hasAttr<OMPDeclareTargetDeclAttr>()1.16k
||
13359
1.20k
               
(22
VD->isExternallyVisible()22
&&
13360
22
                VD->getVisibility() != HiddenVisibility);
13361
1.20k
      });
13362
3.71k
  }
13363
13364
0
  return true;
13365
3.67k
}
13366
13367
StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
13368
                                                Stmt *AStmt,
13369
                                                SourceLocation StartLoc,
13370
5.93k
                                                SourceLocation EndLoc) {
13371
5.93k
  if (!AStmt)
13372
31
    return StmtError();
13373
13374
5.90k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13375
13376
  // OpenMP [2.12.2, target data Construct, Restrictions]
13377
  // At least one map, use_device_addr or use_device_ptr clause must appear on
13378
  // the directive.
13379
5.90k
  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13380
5.90k
      
(33
LangOpts.OpenMP < 5033
||
!hasClauses(Clauses, OMPC_use_device_addr)21
)) {
13381
33
    StringRef Expected;
13382
33
    if (LangOpts.OpenMP < 50)
13383
12
      Expected = "'map' or 'use_device_ptr'";
13384
21
    else
13385
21
      Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
13386
33
    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13387
33
        << Expected << getOpenMPDirectiveName(OMPD_target_data);
13388
33
    return StmtError();
13389
33
  }
13390
13391
5.86k
  setFunctionHasBranchProtectedScope();
13392
13393
5.86k
  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13394
5.86k
                                        AStmt);
13395
5.90k
}
13396
13397
StmtResult
13398
Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
13399
                                          SourceLocation StartLoc,
13400
2.36k
                                          SourceLocation EndLoc, Stmt *AStmt) {
13401
2.36k
  if (!AStmt)
13402
0
    return StmtError();
13403
13404
2.36k
  auto *CS = cast<CapturedStmt>(AStmt);
13405
  // 1.2.2 OpenMP Language Terminology
13406
  // Structured block - An executable statement with a single entry at the
13407
  // top and a single exit at the bottom.
13408
  // The point of exit cannot be a branch out of the structured block.
13409
  // longjmp() and throw() must not violate the entry/exit criteria.
13410
2.36k
  CS->getCapturedDecl()->setNothrow();
13411
2.36k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
13412
2.36k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel0
) {
13413
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13414
    // 1.2.2 OpenMP Language Terminology
13415
    // Structured block - An executable statement with a single entry at the
13416
    // top and a single exit at the bottom.
13417
    // The point of exit cannot be a branch out of the structured block.
13418
    // longjmp() and throw() must not violate the entry/exit criteria.
13419
0
    CS->getCapturedDecl()->setNothrow();
13420
0
  }
13421
13422
  // OpenMP [2.10.2, Restrictions, p. 99]
13423
  // At least one map clause must appear on the directive.
13424
2.36k
  if (!hasClauses(Clauses, OMPC_map)) {
13425
10
    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13426
10
        << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13427
10
    return StmtError();
13428
10
  }
13429
13430
2.35k
  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13431
2.35k
                                             AStmt);
13432
2.36k
}
13433
13434
StmtResult
13435
Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
13436
                                         SourceLocation StartLoc,
13437
2.34k
                                         SourceLocation EndLoc, Stmt *AStmt) {
13438
2.34k
  if (!AStmt)
13439
0
    return StmtError();
13440
13441
2.34k
  auto *CS = cast<CapturedStmt>(AStmt);
13442
  // 1.2.2 OpenMP Language Terminology
13443
  // Structured block - An executable statement with a single entry at the
13444
  // top and a single exit at the bottom.
13445
  // The point of exit cannot be a branch out of the structured block.
13446
  // longjmp() and throw() must not violate the entry/exit criteria.
13447
2.34k
  CS->getCapturedDecl()->setNothrow();
13448
2.34k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
13449
2.34k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel0
) {
13450
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13451
    // 1.2.2 OpenMP Language Terminology
13452
    // Structured block - An executable statement with a single entry at the
13453
    // top and a single exit at the bottom.
13454
    // The point of exit cannot be a branch out of the structured block.
13455
    // longjmp() and throw() must not violate the entry/exit criteria.
13456
0
    CS->getCapturedDecl()->setNothrow();
13457
0
  }
13458
13459
  // OpenMP [2.10.3, Restrictions, p. 102]
13460
  // At least one map clause must appear on the directive.
13461
2.34k
  if (!hasClauses(Clauses, OMPC_map)) {
13462
10
    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13463
10
        << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13464
10
    return StmtError();
13465
10
  }
13466
13467
2.33k
  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13468
2.33k
                                            AStmt);
13469
2.34k
}
13470
13471
StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
13472
                                                  SourceLocation StartLoc,
13473
                                                  SourceLocation EndLoc,
13474
4.26k
                                                  Stmt *AStmt) {
13475
4.26k
  if (!AStmt)
13476
0
    return StmtError();
13477
13478
4.26k
  auto *CS = cast<CapturedStmt>(AStmt);
13479
  // 1.2.2 OpenMP Language Terminology
13480
  // Structured block - An executable statement with a single entry at the
13481
  // top and a single exit at the bottom.
13482
  // The point of exit cannot be a branch out of the structured block.
13483
  // longjmp() and throw() must not violate the entry/exit criteria.
13484
4.26k
  CS->getCapturedDecl()->setNothrow();
13485
4.26k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
13486
4.26k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel0
) {
13487
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13488
    // 1.2.2 OpenMP Language Terminology
13489
    // Structured block - An executable statement with a single entry at the
13490
    // top and a single exit at the bottom.
13491
    // The point of exit cannot be a branch out of the structured block.
13492
    // longjmp() and throw() must not violate the entry/exit criteria.
13493
0
    CS->getCapturedDecl()->setNothrow();
13494
0
  }
13495
13496
4.26k
  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
13497
585
    Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13498
585
    return StmtError();
13499
585
  }
13500
13501
3.67k
  if (!isClauseMappable(Clauses)) {
13502
14
    Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13503
14
    return StmtError();
13504
14
  }
13505
13506
3.66k
  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
13507
3.66k
                                          AStmt);
13508
3.67k
}
13509
13510
StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
13511
                                           Stmt *AStmt, SourceLocation StartLoc,
13512
27.2k
                                           SourceLocation EndLoc) {
13513
27.2k
  if (!AStmt)
13514
1.00k
    return StmtError();
13515
13516
  // Report affected OpenMP target offloading behavior when in HIP lang-mode.
13517
26.2k
  if (getLangOpts().HIP && 
(3
DSAStack3
->getParentDirective() == OMPD_target))
13518
2
    Diag(StartLoc, diag::warn_hip_omp_target_directives);
13519
13520
26.2k
  auto *CS = cast<CapturedStmt>(AStmt);
13521
  // 1.2.2 OpenMP Language Terminology
13522
  // Structured block - An executable statement with a single entry at the
13523
  // top and a single exit at the bottom.
13524
  // The point of exit cannot be a branch out of the structured block.
13525
  // longjmp() and throw() must not violate the entry/exit criteria.
13526
26.2k
  CS->getCapturedDecl()->setNothrow();
13527
13528
26.2k
  setFunctionHasBranchProtectedScope();
13529
13530
26.2k
  DSAStack->setParentTeamsRegionLoc(StartLoc);
13531
13532
26.2k
  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13533
27.2k
}
13534
13535
StmtResult
13536
Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
13537
                                            SourceLocation EndLoc,
13538
253
                                            OpenMPDirectiveKind CancelRegion) {
13539
253
  if (DSAStack->isParentNowaitRegion()) {
13540
0
    Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13541
0
    return StmtError();
13542
0
  }
13543
253
  if (DSAStack->isParentOrderedRegion()) {
13544
0
    Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13545
0
    return StmtError();
13546
0
  }
13547
253
  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
13548
253
                                               CancelRegion);
13549
253
}
13550
13551
StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
13552
                                            SourceLocation StartLoc,
13553
                                            SourceLocation EndLoc,
13554
712
                                            OpenMPDirectiveKind CancelRegion) {
13555
712
  if (DSAStack->isParentNowaitRegion()) {
13556
0
    Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13557
0
    return StmtError();
13558
0
  }
13559
712
  if (DSAStack->isParentOrderedRegion()) {
13560
0
    Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13561
0
    return StmtError();
13562
0
  }
13563
712
  DSAStack->setParentCancelRegion(/*Cancel=*/true);
13564
712
  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
13565
712
                                    CancelRegion);
13566
712
}
13567
13568
static bool checkReductionClauseWithNogroup(Sema &S,
13569
57.2k
                                            ArrayRef<OMPClause *> Clauses) {
13570
57.2k
  const OMPClause *ReductionClause = nullptr;
13571
57.2k
  const OMPClause *NogroupClause = nullptr;
13572
57.2k
  for (const OMPClause *C : Clauses) {
13573
38.9k
    if (C->getClauseKind() == OMPC_reduction) {
13574
10.3k
      ReductionClause = C;
13575
10.3k
      if (NogroupClause)
13576
152
        break;
13577
10.1k
      continue;
13578
10.3k
    }
13579
28.6k
    if (C->getClauseKind() == OMPC_nogroup) {
13580
444
      NogroupClause = C;
13581
444
      if (ReductionClause)
13582
68
        break;
13583
376
      continue;
13584
444
    }
13585
28.6k
  }
13586
57.2k
  if (ReductionClause && 
NogroupClause9.83k
) {
13587
220
    S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13588
220
        << SourceRange(NogroupClause->getBeginLoc(),
13589
220
                       NogroupClause->getEndLoc());
13590
220
    return true;
13591
220
  }
13592
56.9k
  return false;
13593
57.2k
}
13594
13595
StmtResult Sema::ActOnOpenMPTaskLoopDirective(
13596
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13597
8.96k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13598
8.96k
  if (!AStmt)
13599
0
    return StmtError();
13600
13601
8.96k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13602
8.96k
  OMPLoopBasedDirective::HelperExprs B;
13603
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13604
  // define the nested loops number.
13605
8.96k
  unsigned NestedLoopCount =
13606
8.96k
      checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
13607
8.96k
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13608
8.96k
                      VarsWithImplicitDSA, B);
13609
8.96k
  if (NestedLoopCount == 0)
13610
270
    return StmtError();
13611
13612
8.69k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13613
8.69k
         "omp for loop exprs were not built");
13614
13615
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13616
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13617
  // not appear on the same taskloop directive.
13618
8.69k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13619
8.69k
                                    {OMPC_grainsize, OMPC_num_tasks}))
13620
12
    return StmtError();
13621
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13622
  // If a reduction clause is present on the taskloop directive, the nogroup
13623
  // clause must not be specified.
13624
8.67k
  if (checkReductionClauseWithNogroup(*this, Clauses))
13625
32
    return StmtError();
13626
13627
8.64k
  setFunctionHasBranchProtectedScope();
13628
8.64k
  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13629
8.64k
                                      NestedLoopCount, Clauses, AStmt, B,
13630
8.64k
                                      DSAStack->isCancelRegion());
13631
8.67k
}
13632
13633
StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
13634
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13635
7.68k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13636
7.68k
  if (!AStmt)
13637
0
    return StmtError();
13638
13639
7.68k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13640
7.68k
  OMPLoopBasedDirective::HelperExprs B;
13641
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13642
  // define the nested loops number.
13643
7.68k
  unsigned NestedLoopCount =
13644
7.68k
      checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
13645
7.68k
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13646
7.68k
                      VarsWithImplicitDSA, B);
13647
7.68k
  if (NestedLoopCount == 0)
13648
322
    return StmtError();
13649
13650
7.36k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13651
7.36k
         "omp for loop exprs were not built");
13652
13653
7.36k
  if (!CurContext->isDependentContext()) {
13654
    // Finalize the clauses that need pre-built expressions for CodeGen.
13655
5.39k
    for (OMPClause *C : Clauses) {
13656
4.01k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
13657
171
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13658
171
                                     B.NumIterations, *this, CurScope,
13659
171
                                     DSAStack))
13660
0
          return StmtError();
13661
4.01k
    }
13662
5.39k
  }
13663
13664
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13665
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13666
  // not appear on the same taskloop directive.
13667
7.36k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13668
7.36k
                                    {OMPC_grainsize, OMPC_num_tasks}))
13669
12
    return StmtError();
13670
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13671
  // If a reduction clause is present on the taskloop directive, the nogroup
13672
  // clause must not be specified.
13673
7.35k
  if (checkReductionClauseWithNogroup(*this, Clauses))
13674
24
    return StmtError();
13675
7.33k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
13676
6
    return StmtError();
13677
13678
7.32k
  setFunctionHasBranchProtectedScope();
13679
7.32k
  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13680
7.32k
                                          NestedLoopCount, Clauses, AStmt, B);
13681
7.33k
}
13682
13683
StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
13684
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13685
6.42k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13686
6.42k
  if (!AStmt)
13687
0
    return StmtError();
13688
13689
6.42k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13690
6.42k
  OMPLoopBasedDirective::HelperExprs B;
13691
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13692
  // define the nested loops number.
13693
6.42k
  unsigned NestedLoopCount =
13694
6.42k
      checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13695
6.42k
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13696
6.42k
                      VarsWithImplicitDSA, B);
13697
6.42k
  if (NestedLoopCount == 0)
13698
270
    return StmtError();
13699
13700
6.15k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13701
6.15k
         "omp for loop exprs were not built");
13702
13703
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13704
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13705
  // not appear on the same taskloop directive.
13706
6.15k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13707
6.15k
                                    {OMPC_grainsize, OMPC_num_tasks}))
13708
12
    return StmtError();
13709
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13710
  // If a reduction clause is present on the taskloop directive, the nogroup
13711
  // clause must not be specified.
13712
6.14k
  if (checkReductionClauseWithNogroup(*this, Clauses))
13713
24
    return StmtError();
13714
13715
6.12k
  setFunctionHasBranchProtectedScope();
13716
6.12k
  return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13717
6.12k
                                            NestedLoopCount, Clauses, AStmt, B,
13718
6.12k
                                            DSAStack->isCancelRegion());
13719
6.14k
}
13720
13721
StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective(
13722
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13723
3.53k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13724
3.53k
  if (!AStmt)
13725
0
    return StmtError();
13726
13727
3.53k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13728
3.53k
  OMPLoopBasedDirective::HelperExprs B;
13729
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13730
  // define the nested loops number.
13731
3.53k
  unsigned NestedLoopCount =
13732
3.53k
      checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses),
13733
3.53k
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13734
3.53k
                      VarsWithImplicitDSA, B);
13735
3.53k
  if (NestedLoopCount == 0)
13736
250
    return StmtError();
13737
13738
3.28k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13739
3.28k
         "omp for loop exprs were not built");
13740
13741
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13742
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13743
  // not appear on the same taskloop directive.
13744
3.28k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13745
3.28k
                                    {OMPC_grainsize, OMPC_num_tasks}))
13746
12
    return StmtError();
13747
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13748
  // If a reduction clause is present on the taskloop directive, the nogroup
13749
  // clause must not be specified.
13750
3.27k
  if (checkReductionClauseWithNogroup(*this, Clauses))
13751
0
    return StmtError();
13752
13753
3.27k
  setFunctionHasBranchProtectedScope();
13754
3.27k
  return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13755
3.27k
                                            NestedLoopCount, Clauses, AStmt, B,
13756
3.27k
                                            DSAStack->isCancelRegion());
13757
3.27k
}
13758
13759
StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
13760
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13761
7.50k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13762
7.50k
  if (!AStmt)
13763
0
    return StmtError();
13764
13765
7.50k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13766
7.50k
  OMPLoopBasedDirective::HelperExprs B;
13767
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13768
  // define the nested loops number.
13769
7.50k
  unsigned NestedLoopCount =
13770
7.50k
      checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13771
7.50k
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13772
7.50k
                      VarsWithImplicitDSA, B);
13773
7.50k
  if (NestedLoopCount == 0)
13774
302
    return StmtError();
13775
13776
7.19k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13777
7.19k
         "omp for loop exprs were not built");
13778
13779
7.19k
  if (!CurContext->isDependentContext()) {
13780
    // Finalize the clauses that need pre-built expressions for CodeGen.
13781
5.22k
    for (OMPClause *C : Clauses) {
13782
3.95k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
13783
168
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13784
168
                                     B.NumIterations, *this, CurScope,
13785
168
                                     DSAStack))
13786
0
          return StmtError();
13787
3.95k
    }
13788
5.22k
  }
13789
13790
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13791
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13792
  // not appear on the same taskloop directive.
13793
7.19k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13794
7.19k
                                    {OMPC_grainsize, OMPC_num_tasks}))
13795
12
    return StmtError();
13796
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13797
  // If a reduction clause is present on the taskloop directive, the nogroup
13798
  // clause must not be specified.
13799
7.18k
  if (checkReductionClauseWithNogroup(*this, Clauses))
13800
24
    return StmtError();
13801
7.16k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
13802
4
    return StmtError();
13803
13804
7.15k
  setFunctionHasBranchProtectedScope();
13805
7.15k
  return OMPMasterTaskLoopSimdDirective::Create(
13806
7.15k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13807
7.16k
}
13808
13809
StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective(
13810
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13811
6.65k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13812
6.65k
  if (!AStmt)
13813
0
    return StmtError();
13814
13815
6.65k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13816
6.65k
  OMPLoopBasedDirective::HelperExprs B;
13817
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13818
  // define the nested loops number.
13819
6.65k
  unsigned NestedLoopCount =
13820
6.65k
      checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13821
6.65k
                      /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13822
6.65k
                      VarsWithImplicitDSA, B);
13823
6.65k
  if (NestedLoopCount == 0)
13824
262
    return StmtError();
13825
13826
6.39k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13827
6.39k
         "omp for loop exprs were not built");
13828
13829
6.39k
  if (!CurContext->isDependentContext()) {
13830
    // Finalize the clauses that need pre-built expressions for CodeGen.
13831
4.56k
    for (OMPClause *C : Clauses) {
13832
3.64k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
13833
165
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13834
165
                                     B.NumIterations, *this, CurScope,
13835
165
                                     DSAStack))
13836
0
          return StmtError();
13837
3.64k
    }
13838
4.56k
  }
13839
13840
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13841
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13842
  // not appear on the same taskloop directive.
13843
6.39k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13844
6.39k
                                    {OMPC_grainsize, OMPC_num_tasks}))
13845
12
    return StmtError();
13846
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13847
  // If a reduction clause is present on the taskloop directive, the nogroup
13848
  // clause must not be specified.
13849
6.37k
  if (checkReductionClauseWithNogroup(*this, Clauses))
13850
20
    return StmtError();
13851
6.35k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
13852
0
    return StmtError();
13853
13854
6.35k
  setFunctionHasBranchProtectedScope();
13855
6.35k
  return OMPMaskedTaskLoopSimdDirective::Create(
13856
6.35k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13857
6.35k
}
13858
13859
StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
13860
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13861
4.47k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13862
4.47k
  if (!AStmt)
13863
0
    return StmtError();
13864
13865
4.47k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13866
4.47k
  auto *CS = cast<CapturedStmt>(AStmt);
13867
  // 1.2.2 OpenMP Language Terminology
13868
  // Structured block - An executable statement with a single entry at the
13869
  // top and a single exit at the bottom.
13870
  // The point of exit cannot be a branch out of the structured block.
13871
  // longjmp() and throw() must not violate the entry/exit criteria.
13872
4.47k
  CS->getCapturedDecl()->setNothrow();
13873
4.47k
  for (int ThisCaptureLevel =
13874
4.47k
           getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13875
8.94k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel4.47k
) {
13876
4.47k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13877
    // 1.2.2 OpenMP Language Terminology
13878
    // Structured block - An executable statement with a single entry at the
13879
    // top and a single exit at the bottom.
13880
    // The point of exit cannot be a branch out of the structured block.
13881
    // longjmp() and throw() must not violate the entry/exit criteria.
13882
4.47k
    CS->getCapturedDecl()->setNothrow();
13883
4.47k
  }
13884
13885
4.47k
  OMPLoopBasedDirective::HelperExprs B;
13886
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13887
  // define the nested loops number.
13888
4.47k
  unsigned NestedLoopCount = checkOpenMPLoop(
13889
4.47k
      OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13890
4.47k
      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13891
4.47k
      VarsWithImplicitDSA, B);
13892
4.47k
  if (NestedLoopCount == 0)
13893
270
    return StmtError();
13894
13895
4.20k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13896
4.20k
         "omp for loop exprs were not built");
13897
13898
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13899
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13900
  // not appear on the same taskloop directive.
13901
4.20k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13902
4.20k
                                    {OMPC_grainsize, OMPC_num_tasks}))
13903
12
    return StmtError();
13904
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13905
  // If a reduction clause is present on the taskloop directive, the nogroup
13906
  // clause must not be specified.
13907
4.19k
  if (checkReductionClauseWithNogroup(*this, Clauses))
13908
24
    return StmtError();
13909
13910
4.16k
  setFunctionHasBranchProtectedScope();
13911
4.16k
  return OMPParallelMasterTaskLoopDirective::Create(
13912
4.16k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13913
4.16k
      DSAStack->isCancelRegion());
13914
4.19k
}
13915
13916
StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective(
13917
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13918
4.15k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13919
4.15k
  if (!AStmt)
13920
0
    return StmtError();
13921
13922
4.15k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13923
4.15k
  auto *CS = cast<CapturedStmt>(AStmt);
13924
  // 1.2.2 OpenMP Language Terminology
13925
  // Structured block - An executable statement with a single entry at the
13926
  // top and a single exit at the bottom.
13927
  // The point of exit cannot be a branch out of the structured block.
13928
  // longjmp() and throw() must not violate the entry/exit criteria.
13929
4.15k
  CS->getCapturedDecl()->setNothrow();
13930
4.15k
  for (int ThisCaptureLevel =
13931
4.15k
           getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop);
13932
8.31k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel4.15k
) {
13933
4.15k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13934
    // 1.2.2 OpenMP Language Terminology
13935
    // Structured block - An executable statement with a single entry at the
13936
    // top and a single exit at the bottom.
13937
    // The point of exit cannot be a branch out of the structured block.
13938
    // longjmp() and throw() must not violate the entry/exit criteria.
13939
4.15k
    CS->getCapturedDecl()->setNothrow();
13940
4.15k
  }
13941
13942
4.15k
  OMPLoopBasedDirective::HelperExprs B;
13943
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13944
  // define the nested loops number.
13945
4.15k
  unsigned NestedLoopCount = checkOpenMPLoop(
13946
4.15k
      OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses),
13947
4.15k
      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13948
4.15k
      VarsWithImplicitDSA, B);
13949
4.15k
  if (NestedLoopCount == 0)
13950
250
    return StmtError();
13951
13952
3.90k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
13953
3.90k
         "omp for loop exprs were not built");
13954
13955
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13956
  // The grainsize clause and num_tasks clause are mutually exclusive and may
13957
  // not appear on the same taskloop directive.
13958
3.90k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
13959
3.90k
                                    {OMPC_grainsize, OMPC_num_tasks}))
13960
8
    return StmtError();
13961
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13962
  // If a reduction clause is present on the taskloop directive, the nogroup
13963
  // clause must not be specified.
13964
3.89k
  if (checkReductionClauseWithNogroup(*this, Clauses))
13965
24
    return StmtError();
13966
13967
3.87k
  setFunctionHasBranchProtectedScope();
13968
3.87k
  return OMPParallelMaskedTaskLoopDirective::Create(
13969
3.87k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13970
3.87k
      DSAStack->isCancelRegion());
13971
3.89k
}
13972
13973
StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
13974
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13975
5.56k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13976
5.56k
  if (!AStmt)
13977
0
    return StmtError();
13978
13979
5.56k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13980
5.56k
  auto *CS = cast<CapturedStmt>(AStmt);
13981
  // 1.2.2 OpenMP Language Terminology
13982
  // Structured block - An executable statement with a single entry at the
13983
  // top and a single exit at the bottom.
13984
  // The point of exit cannot be a branch out of the structured block.
13985
  // longjmp() and throw() must not violate the entry/exit criteria.
13986
5.56k
  CS->getCapturedDecl()->setNothrow();
13987
5.56k
  for (int ThisCaptureLevel =
13988
5.56k
           getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
13989
11.1k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel5.56k
) {
13990
5.56k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
13991
    // 1.2.2 OpenMP Language Terminology
13992
    // Structured block - An executable statement with a single entry at the
13993
    // top and a single exit at the bottom.
13994
    // The point of exit cannot be a branch out of the structured block.
13995
    // longjmp() and throw() must not violate the entry/exit criteria.
13996
5.56k
    CS->getCapturedDecl()->setNothrow();
13997
5.56k
  }
13998
13999
5.56k
  OMPLoopBasedDirective::HelperExprs B;
14000
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14001
  // define the nested loops number.
14002
5.56k
  unsigned NestedLoopCount = checkOpenMPLoop(
14003
5.56k
      OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
14004
5.56k
      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
14005
5.56k
      VarsWithImplicitDSA, B);
14006
5.56k
  if (NestedLoopCount == 0)
14007
302
    return StmtError();
14008
14009
5.26k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14010
5.26k
         "omp for loop exprs were not built");
14011
14012
5.26k
  if (!CurContext->isDependentContext()) {
14013
    // Finalize the clauses that need pre-built expressions for CodeGen.
14014
3.84k
    for (OMPClause *C : Clauses) {
14015
2.93k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14016
157
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14017
157
                                     B.NumIterations, *this, CurScope,
14018
157
                                     DSAStack))
14019
0
          return StmtError();
14020
2.93k
    }
14021
3.84k
  }
14022
14023
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14024
  // The grainsize clause and num_tasks clause are mutually exclusive and may
14025
  // not appear on the same taskloop directive.
14026
5.26k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
14027
5.26k
                                    {OMPC_grainsize, OMPC_num_tasks}))
14028
12
    return StmtError();
14029
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14030
  // If a reduction clause is present on the taskloop directive, the nogroup
14031
  // clause must not be specified.
14032
5.25k
  if (checkReductionClauseWithNogroup(*this, Clauses))
14033
24
    return StmtError();
14034
5.22k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14035
0
    return StmtError();
14036
14037
5.22k
  setFunctionHasBranchProtectedScope();
14038
5.22k
  return OMPParallelMasterTaskLoopSimdDirective::Create(
14039
5.22k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14040
5.22k
}
14041
14042
StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
14043
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14044
5.12k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14045
5.12k
  if (!AStmt)
14046
0
    return StmtError();
14047
14048
5.12k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14049
5.12k
  auto *CS = cast<CapturedStmt>(AStmt);
14050
  // 1.2.2 OpenMP Language Terminology
14051
  // Structured block - An executable statement with a single entry at the
14052
  // top and a single exit at the bottom.
14053
  // The point of exit cannot be a branch out of the structured block.
14054
  // longjmp() and throw() must not violate the entry/exit criteria.
14055
5.12k
  CS->getCapturedDecl()->setNothrow();
14056
5.12k
  for (int ThisCaptureLevel =
14057
5.12k
           getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd);
14058
10.2k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel5.12k
) {
14059
5.12k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14060
    // 1.2.2 OpenMP Language Terminology
14061
    // Structured block - An executable statement with a single entry at the
14062
    // top and a single exit at the bottom.
14063
    // The point of exit cannot be a branch out of the structured block.
14064
    // longjmp() and throw() must not violate the entry/exit criteria.
14065
5.12k
    CS->getCapturedDecl()->setNothrow();
14066
5.12k
  }
14067
14068
5.12k
  OMPLoopBasedDirective::HelperExprs B;
14069
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14070
  // define the nested loops number.
14071
5.12k
  unsigned NestedLoopCount = checkOpenMPLoop(
14072
5.12k
      OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
14073
5.12k
      /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
14074
5.12k
      VarsWithImplicitDSA, B);
14075
5.12k
  if (NestedLoopCount == 0)
14076
262
    return StmtError();
14077
14078
4.86k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14079
4.86k
         "omp for loop exprs were not built");
14080
14081
4.86k
  if (!CurContext->isDependentContext()) {
14082
    // Finalize the clauses that need pre-built expressions for CodeGen.
14083
3.47k
    for (OMPClause *C : Clauses) {
14084
2.43k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14085
146
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14086
146
                                     B.NumIterations, *this, CurScope,
14087
146
                                     DSAStack))
14088
0
          return StmtError();
14089
2.43k
    }
14090
3.47k
  }
14091
14092
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14093
  // The grainsize clause and num_tasks clause are mutually exclusive and may
14094
  // not appear on the same taskloop directive.
14095
4.86k
  if (checkMutuallyExclusiveClauses(*this, Clauses,
14096
4.86k
                                    {OMPC_grainsize, OMPC_num_tasks}))
14097
12
    return StmtError();
14098
  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14099
  // If a reduction clause is present on the taskloop directive, the nogroup
14100
  // clause must not be specified.
14101
4.85k
  if (checkReductionClauseWithNogroup(*this, Clauses))
14102
24
    return StmtError();
14103
4.82k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14104
0
    return StmtError();
14105
14106
4.82k
  setFunctionHasBranchProtectedScope();
14107
4.82k
  return OMPParallelMaskedTaskLoopSimdDirective::Create(
14108
4.82k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14109
4.82k
}
14110
14111
StmtResult Sema::ActOnOpenMPDistributeDirective(
14112
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14113
2.13k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14114
2.13k
  if (!AStmt)
14115
0
    return StmtError();
14116
14117
2.13k
  if (!checkLastPrivateForMappedDirectives(Clauses))
14118
0
    return StmtError();
14119
14120
2.13k
  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14121
2.13k
  OMPLoopBasedDirective::HelperExprs B;
14122
  // In presence of clause 'collapse' with number of loops, it will
14123
  // define the nested loops number.
14124
2.13k
  unsigned NestedLoopCount =
14125
2.13k
      checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
14126
2.13k
                      nullptr /*ordered not a clause on distribute*/, AStmt,
14127
2.13k
                      *this, *DSAStack, VarsWithImplicitDSA, B);
14128
2.13k
  if (NestedLoopCount == 0)
14129
42
    return StmtError();
14130
14131
2.09k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14132
2.09k
         "omp for loop exprs were not built");
14133
14134
2.09k
  setFunctionHasBranchProtectedScope();
14135
2.09k
  auto *DistributeDirective = OMPDistributeDirective::Create(
14136
2.09k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14137
2.09k
      DSAStack->getMappedDirective());
14138
2.09k
  return DistributeDirective;
14139
2.09k
}
14140
14141
StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
14142
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14143
6.71k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14144
6.71k
  if (!AStmt)
14145
0
    return StmtError();
14146
14147
6.71k
  auto *CS = cast<CapturedStmt>(AStmt);
14148
  // 1.2.2 OpenMP Language Terminology
14149
  // Structured block - An executable statement with a single entry at the
14150
  // top and a single exit at the bottom.
14151
  // The point of exit cannot be a branch out of the structured block.
14152
  // longjmp() and throw() must not violate the entry/exit criteria.
14153
6.71k
  CS->getCapturedDecl()->setNothrow();
14154
6.71k
  for (int ThisCaptureLevel =
14155
6.71k
           getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
14156
6.71k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel0
) {
14157
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14158
    // 1.2.2 OpenMP Language Terminology
14159
    // Structured block - An executable statement with a single entry at the
14160
    // top and a single exit at the bottom.
14161
    // The point of exit cannot be a branch out of the structured block.
14162
    // longjmp() and throw() must not violate the entry/exit criteria.
14163
0
    CS->getCapturedDecl()->setNothrow();
14164
0
  }
14165
14166
6.71k
  OMPLoopBasedDirective::HelperExprs B;
14167
  // In presence of clause 'collapse' with number of loops, it will
14168
  // define the nested loops number.
14169
6.71k
  unsigned NestedLoopCount = checkOpenMPLoop(
14170
6.71k
      OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14171
6.71k
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14172
6.71k
      VarsWithImplicitDSA, B);
14173
6.71k
  if (NestedLoopCount == 0)
14174
44
    return StmtError();
14175
14176
6.66k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14177
6.66k
         "omp for loop exprs were not built");
14178
14179
6.66k
  setFunctionHasBranchProtectedScope();
14180
6.66k
  return OMPDistributeParallelForDirective::Create(
14181
6.66k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14182
6.66k
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14183
6.66k
}
14184
14185
StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
14186
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14187
8.35k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14188
8.35k
  if (!AStmt)
14189
6
    return StmtError();
14190
14191
8.35k
  auto *CS = cast<CapturedStmt>(AStmt);
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
8.35k
  CS->getCapturedDecl()->setNothrow();
14198
8.35k
  for (int ThisCaptureLevel =
14199
8.35k
           getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
14200
8.35k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel0
) {
14201
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14202
    // 1.2.2 OpenMP Language Terminology
14203
    // Structured block - An executable statement with a single entry at the
14204
    // top and a single exit at the bottom.
14205
    // The point of exit cannot be a branch out of the structured block.
14206
    // longjmp() and throw() must not violate the entry/exit criteria.
14207
0
    CS->getCapturedDecl()->setNothrow();
14208
0
  }
14209
14210
8.35k
  OMPLoopBasedDirective::HelperExprs B;
14211
  // In presence of clause 'collapse' with number of loops, it will
14212
  // define the nested loops number.
14213
8.35k
  unsigned NestedLoopCount = checkOpenMPLoop(
14214
8.35k
      OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14215
8.35k
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14216
8.35k
      VarsWithImplicitDSA, B);
14217
8.35k
  if (NestedLoopCount == 0)
14218
323
    return StmtError();
14219
14220
8.02k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14221
8.02k
         "omp for loop exprs were not built");
14222
14223
8.02k
  if (!CurContext->isDependentContext()) {
14224
    // Finalize the clauses that need pre-built expressions for CodeGen.
14225
5.86k
    for (OMPClause *C : Clauses) {
14226
3.11k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14227
112
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14228
112
                                     B.NumIterations, *this, CurScope,
14229
112
                                     DSAStack))
14230
68
          return StmtError();
14231
3.11k
    }
14232
5.86k
  }
14233
14234
7.95k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14235
12
    return StmtError();
14236
14237
7.94k
  setFunctionHasBranchProtectedScope();
14238
7.94k
  return OMPDistributeParallelForSimdDirective::Create(
14239
7.94k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14240
7.95k
}
14241
14242
StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
14243
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14244
6.79k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14245
6.79k
  if (!AStmt)
14246
6
    return StmtError();
14247
14248
6.78k
  auto *CS = cast<CapturedStmt>(AStmt);
14249
  // 1.2.2 OpenMP Language Terminology
14250
  // Structured block - An executable statement with a single entry at the
14251
  // top and a single exit at the bottom.
14252
  // The point of exit cannot be a branch out of the structured block.
14253
  // longjmp() and throw() must not violate the entry/exit criteria.
14254
6.78k
  CS->getCapturedDecl()->setNothrow();
14255
6.78k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
14256
6.78k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel0
) {
14257
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14258
    // 1.2.2 OpenMP Language Terminology
14259
    // Structured block - An executable statement with a single entry at the
14260
    // top and a single exit at the bottom.
14261
    // The point of exit cannot be a branch out of the structured block.
14262
    // longjmp() and throw() must not violate the entry/exit criteria.
14263
0
    CS->getCapturedDecl()->setNothrow();
14264
0
  }
14265
14266
6.78k
  OMPLoopBasedDirective::HelperExprs B;
14267
  // In presence of clause 'collapse' with number of loops, it will
14268
  // define the nested loops number.
14269
6.78k
  unsigned NestedLoopCount =
14270
6.78k
      checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
14271
6.78k
                      nullptr /*ordered not a clause on distribute*/, CS, *this,
14272
6.78k
                      *DSAStack, VarsWithImplicitDSA, B);
14273
6.78k
  if (NestedLoopCount == 0)
14274
310
    return StmtError();
14275
14276
6.47k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14277
6.47k
         "omp for loop exprs were not built");
14278
14279
6.47k
  if (!CurContext->isDependentContext()) {
14280
    // Finalize the clauses that need pre-built expressions for CodeGen.
14281
4.98k
    for (OMPClause *C : Clauses) {
14282
2.78k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14283
186
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14284
186
                                     B.NumIterations, *this, CurScope,
14285
186
                                     DSAStack))
14286
68
          return StmtError();
14287
2.78k
    }
14288
4.98k
  }
14289
14290
6.41k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14291
12
    return StmtError();
14292
14293
6.39k
  setFunctionHasBranchProtectedScope();
14294
6.39k
  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
14295
6.39k
                                            NestedLoopCount, Clauses, AStmt, B);
14296
6.41k
}
14297
14298
StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
14299
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14300
10.5k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14301
10.5k
  if (!AStmt)
14302
70
    return StmtError();
14303
14304
10.4k
  auto *CS = cast<CapturedStmt>(AStmt);
14305
  // 1.2.2 OpenMP Language Terminology
14306
  // Structured block - An executable statement with a single entry at the
14307
  // top and a single exit at the bottom.
14308
  // The point of exit cannot be a branch out of the structured block.
14309
  // longjmp() and throw() must not violate the entry/exit criteria.
14310
10.4k
  CS->getCapturedDecl()->setNothrow();
14311
10.4k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
14312
31.4k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel20.9k
) {
14313
20.9k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14314
    // 1.2.2 OpenMP Language Terminology
14315
    // Structured block - An executable statement with a single entry at the
14316
    // top and a single exit at the bottom.
14317
    // The point of exit cannot be a branch out of the structured block.
14318
    // longjmp() and throw() must not violate the entry/exit criteria.
14319
20.9k
    CS->getCapturedDecl()->setNothrow();
14320
20.9k
  }
14321
14322
10.4k
  OMPLoopBasedDirective::HelperExprs B;
14323
  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14324
  // define the nested loops number.
14325
10.4k
  unsigned NestedLoopCount = checkOpenMPLoop(
14326
10.4k
      OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
14327
10.4k
      getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA,
14328
10.4k
      B);
14329
10.4k
  if (NestedLoopCount == 0)
14330
412
    return StmtError();
14331
14332
10.0k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14333
10.0k
         "omp target parallel for simd loop exprs were not built");
14334
14335
10.0k
  if (!CurContext->isDependentContext()) {
14336
    // Finalize the clauses that need pre-built expressions for CodeGen.
14337
10.0k
    for (OMPClause *C : Clauses) {
14338
10.0k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14339
241
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14340
241
                                     B.NumIterations, *this, CurScope,
14341
241
                                     DSAStack))
14342
0
          return StmtError();
14343
10.0k
    }
14344
7.55k
  }
14345
10.0k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14346
20
    return StmtError();
14347
14348
10.0k
  setFunctionHasBranchProtectedScope();
14349
10.0k
  return OMPTargetParallelForSimdDirective::Create(
14350
10.0k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14351
10.0k
}
14352
14353
StmtResult Sema::ActOnOpenMPTargetSimdDirective(
14354
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14355
11.1k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14356
11.1k
  if (!AStmt)
14357
0
    return StmtError();
14358
14359
11.1k
  auto *CS = cast<CapturedStmt>(AStmt);
14360
  // 1.2.2 OpenMP Language Terminology
14361
  // Structured block - An executable statement with a single entry at the
14362
  // top and a single exit at the bottom.
14363
  // The point of exit cannot be a branch out of the structured block.
14364
  // longjmp() and throw() must not violate the entry/exit criteria.
14365
11.1k
  CS->getCapturedDecl()->setNothrow();
14366
11.1k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
14367
22.2k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel11.1k
) {
14368
11.1k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14369
    // 1.2.2 OpenMP Language Terminology
14370
    // Structured block - An executable statement with a single entry at the
14371
    // top and a single exit at the bottom.
14372
    // The point of exit cannot be a branch out of the structured block.
14373
    // longjmp() and throw() must not violate the entry/exit criteria.
14374
11.1k
    CS->getCapturedDecl()->setNothrow();
14375
11.1k
  }
14376
14377
11.1k
  OMPLoopBasedDirective::HelperExprs B;
14378
  // In presence of clause 'collapse' with number of loops, it will define the
14379
  // nested loops number.
14380
11.1k
  unsigned NestedLoopCount =
14381
11.1k
      checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
14382
11.1k
                      getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
14383
11.1k
                      VarsWithImplicitDSA, B);
14384
11.1k
  if (NestedLoopCount == 0)
14385
390
    return StmtError();
14386
14387
10.7k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14388
10.7k
         "omp target simd loop exprs were not built");
14389
14390
10.7k
  if (!CurContext->isDependentContext()) {
14391
    // Finalize the clauses that need pre-built expressions for CodeGen.
14392
8.82k
    for (OMPClause *C : Clauses) {
14393
8.82k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14394
242
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14395
242
                                     B.NumIterations, *this, CurScope,
14396
242
                                     DSAStack))
14397
0
          return StmtError();
14398
8.82k
    }
14399
7.92k
  }
14400
14401
10.7k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14402
20
    return StmtError();
14403
14404
10.6k
  setFunctionHasBranchProtectedScope();
14405
10.6k
  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
14406
10.6k
                                        NestedLoopCount, Clauses, AStmt, B);
14407
10.7k
}
14408
14409
StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
14410
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14411
6.10k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14412
6.10k
  if (!AStmt)
14413
4
    return StmtError();
14414
14415
6.09k
  auto *CS = cast<CapturedStmt>(AStmt);
14416
  // 1.2.2 OpenMP Language Terminology
14417
  // Structured block - An executable statement with a single entry at the
14418
  // top and a single exit at the bottom.
14419
  // The point of exit cannot be a branch out of the structured block.
14420
  // longjmp() and throw() must not violate the entry/exit criteria.
14421
6.09k
  CS->getCapturedDecl()->setNothrow();
14422
6.09k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
14423
6.09k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel0
) {
14424
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14425
    // 1.2.2 OpenMP Language Terminology
14426
    // Structured block - An executable statement with a single entry at the
14427
    // top and a single exit at the bottom.
14428
    // The point of exit cannot be a branch out of the structured block.
14429
    // longjmp() and throw() must not violate the entry/exit criteria.
14430
0
    CS->getCapturedDecl()->setNothrow();
14431
0
  }
14432
14433
6.09k
  OMPLoopBasedDirective::HelperExprs B;
14434
  // In presence of clause 'collapse' with number of loops, it will
14435
  // define the nested loops number.
14436
6.09k
  unsigned NestedLoopCount =
14437
6.09k
      checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
14438
6.09k
                      nullptr /*ordered not a clause on distribute*/, CS, *this,
14439
6.09k
                      *DSAStack, VarsWithImplicitDSA, B);
14440
6.09k
  if (NestedLoopCount == 0)
14441
250
    return StmtError();
14442
14443
5.84k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14444
5.84k
         "omp teams distribute loop exprs were not built");
14445
14446
5.84k
  setFunctionHasBranchProtectedScope();
14447
14448
5.84k
  DSAStack->setParentTeamsRegionLoc(StartLoc);
14449
14450
5.84k
  return OMPTeamsDistributeDirective::Create(
14451
5.84k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14452
5.84k
}
14453
14454
StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
14455
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14456
6.78k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14457
6.78k
  if (!AStmt)
14458
6
    return StmtError();
14459
14460
6.77k
  auto *CS = cast<CapturedStmt>(AStmt);
14461
  // 1.2.2 OpenMP Language Terminology
14462
  // Structured block - An executable statement with a single entry at the
14463
  // top and a single exit at the bottom.
14464
  // The point of exit cannot be a branch out of the structured block.
14465
  // longjmp() and throw() must not violate the entry/exit criteria.
14466
6.77k
  CS->getCapturedDecl()->setNothrow();
14467
6.77k
  for (int ThisCaptureLevel =
14468
6.77k
           getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
14469
6.77k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel0
) {
14470
0
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14471
    // 1.2.2 OpenMP Language Terminology
14472
    // Structured block - An executable statement with a single entry at the
14473
    // top and a single exit at the bottom.
14474
    // The point of exit cannot be a branch out of the structured block.
14475
    // longjmp() and throw() must not violate the entry/exit criteria.
14476
0
    CS->getCapturedDecl()->setNothrow();
14477
0
  }
14478
14479
6.77k
  OMPLoopBasedDirective::HelperExprs B;
14480
  // In presence of clause 'collapse' with number of loops, it will
14481
  // define the nested loops number.
14482
6.77k
  unsigned NestedLoopCount = checkOpenMPLoop(
14483
6.77k
      OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14484
6.77k
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14485
6.77k
      VarsWithImplicitDSA, B);
14486
14487
6.77k
  if (NestedLoopCount == 0)
14488
262
    return StmtError();
14489
14490
6.51k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14491
6.51k
         "omp teams distribute simd loop exprs were not built");
14492
14493
6.51k
  if (!CurContext->isDependentContext()) {
14494
    // Finalize the clauses that need pre-built expressions for CodeGen.
14495
4.63k
    for (OMPClause *C : Clauses) {
14496
1.96k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14497
84
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14498
84
                                     B.NumIterations, *this, CurScope,
14499
84
                                     DSAStack))
14500
72
          return StmtError();
14501
1.96k
    }
14502
4.63k
  }
14503
14504
6.44k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14505
0
    return StmtError();
14506
14507
6.44k
  setFunctionHasBranchProtectedScope();
14508
14509
6.44k
  DSAStack->setParentTeamsRegionLoc(StartLoc);
14510
14511
6.44k
  return OMPTeamsDistributeSimdDirective::Create(
14512
6.44k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14513
6.44k
}
14514
14515
StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
14516
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14517
7.65k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14518
7.65k
  if (!AStmt)
14519
6
    return StmtError();
14520
14521
7.64k
  auto *CS = cast<CapturedStmt>(AStmt);
14522
  // 1.2.2 OpenMP Language Terminology
14523
  // Structured block - An executable statement with a single entry at the
14524
  // top and a single exit at the bottom.
14525
  // The point of exit cannot be a branch out of the structured block.
14526
  // longjmp() and throw() must not violate the entry/exit criteria.
14527
7.64k
  CS->getCapturedDecl()->setNothrow();
14528
14529
7.64k
  for (int ThisCaptureLevel =
14530
7.64k
           getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
14531
15.2k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel7.64k
) {
14532
7.64k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14533
    // 1.2.2 OpenMP Language Terminology
14534
    // Structured block - An executable statement with a single entry at the
14535
    // top and a single exit at the bottom.
14536
    // The point of exit cannot be a branch out of the structured block.
14537
    // longjmp() and throw() must not violate the entry/exit criteria.
14538
7.64k
    CS->getCapturedDecl()->setNothrow();
14539
7.64k
  }
14540
14541
7.64k
  OMPLoopBasedDirective::HelperExprs B;
14542
  // In presence of clause 'collapse' with number of loops, it will
14543
  // define the nested loops number.
14544
7.64k
  unsigned NestedLoopCount = checkOpenMPLoop(
14545
7.64k
      OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14546
7.64k
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14547
7.64k
      VarsWithImplicitDSA, B);
14548
14549
7.64k
  if (NestedLoopCount == 0)
14550
262
    return StmtError();
14551
14552
7.38k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14553
7.38k
         "omp for loop exprs were not built");
14554
14555
7.38k
  if (!CurContext->isDependentContext()) {
14556
    // Finalize the clauses that need pre-built expressions for CodeGen.
14557
5.20k
    for (OMPClause *C : Clauses) {
14558
2.43k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14559
108
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14560
108
                                     B.NumIterations, *this, CurScope,
14561
108
                                     DSAStack))
14562
72
          return StmtError();
14563
2.43k
    }
14564
5.20k
  }
14565
14566
7.31k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14567
0
    return StmtError();
14568
14569
7.31k
  setFunctionHasBranchProtectedScope();
14570
14571
7.31k
  DSAStack->setParentTeamsRegionLoc(StartLoc);
14572
14573
7.31k
  return OMPTeamsDistributeParallelForSimdDirective::Create(
14574
7.31k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14575
7.31k
}
14576
14577
StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
14578
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14579
6.61k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14580
6.61k
  if (!AStmt)
14581
6
    return StmtError();
14582
14583
6.61k
  auto *CS = cast<CapturedStmt>(AStmt);
14584
  // 1.2.2 OpenMP Language Terminology
14585
  // Structured block - An executable statement with a single entry at the
14586
  // top and a single exit at the bottom.
14587
  // The point of exit cannot be a branch out of the structured block.
14588
  // longjmp() and throw() must not violate the entry/exit criteria.
14589
6.61k
  CS->getCapturedDecl()->setNothrow();
14590
14591
6.61k
  for (int ThisCaptureLevel =
14592
6.61k
           getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
14593
13.2k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel6.61k
) {
14594
6.61k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14595
    // 1.2.2 OpenMP Language Terminology
14596
    // Structured block - An executable statement with a single entry at the
14597
    // top and a single exit at the bottom.
14598
    // The point of exit cannot be a branch out of the structured block.
14599
    // longjmp() and throw() must not violate the entry/exit criteria.
14600
6.61k
    CS->getCapturedDecl()->setNothrow();
14601
6.61k
  }
14602
14603
6.61k
  OMPLoopBasedDirective::HelperExprs B;
14604
  // In presence of clause 'collapse' with number of loops, it will
14605
  // define the nested loops number.
14606
6.61k
  unsigned NestedLoopCount = checkOpenMPLoop(
14607
6.61k
      OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14608
6.61k
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14609
6.61k
      VarsWithImplicitDSA, B);
14610
14611
6.61k
  if (NestedLoopCount == 0)
14612
252
    return StmtError();
14613
14614
6.35k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14615
6.35k
         "omp for loop exprs were not built");
14616
14617
6.35k
  setFunctionHasBranchProtectedScope();
14618
14619
6.35k
  DSAStack->setParentTeamsRegionLoc(StartLoc);
14620
14621
6.35k
  return OMPTeamsDistributeParallelForDirective::Create(
14622
6.35k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14623
6.35k
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14624
6.35k
}
14625
14626
StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
14627
                                                 Stmt *AStmt,
14628
                                                 SourceLocation StartLoc,
14629
9.89k
                                                 SourceLocation EndLoc) {
14630
9.89k
  if (!AStmt)
14631
180
    return StmtError();
14632
14633
9.71k
  auto *CS = cast<CapturedStmt>(AStmt);
14634
  // 1.2.2 OpenMP Language Terminology
14635
  // Structured block - An executable statement with a single entry at the
14636
  // top and a single exit at the bottom.
14637
  // The point of exit cannot be a branch out of the structured block.
14638
  // longjmp() and throw() must not violate the entry/exit criteria.
14639
9.71k
  CS->getCapturedDecl()->setNothrow();
14640
14641
9.71k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
14642
29.1k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel19.4k
) {
14643
19.4k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14644
    // 1.2.2 OpenMP Language Terminology
14645
    // Structured block - An executable statement with a single entry at the
14646
    // top and a single exit at the bottom.
14647
    // The point of exit cannot be a branch out of the structured block.
14648
    // longjmp() and throw() must not violate the entry/exit criteria.
14649
19.4k
    CS->getCapturedDecl()->setNothrow();
14650
19.4k
  }
14651
9.71k
  setFunctionHasBranchProtectedScope();
14652
14653
9.71k
  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
14654
9.71k
                                         AStmt);
14655
9.89k
}
14656
14657
StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
14658
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14659
9.39k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14660
9.39k
  if (!AStmt)
14661
0
    return StmtError();
14662
14663
9.39k
  auto *CS = cast<CapturedStmt>(AStmt);
14664
  // 1.2.2 OpenMP Language Terminology
14665
  // Structured block - An executable statement with a single entry at the
14666
  // top and a single exit at the bottom.
14667
  // The point of exit cannot be a branch out of the structured block.
14668
  // longjmp() and throw() must not violate the entry/exit criteria.
14669
9.39k
  CS->getCapturedDecl()->setNothrow();
14670
9.39k
  for (int ThisCaptureLevel =
14671
9.39k
           getOpenMPCaptureLevels(OMPD_target_teams_distribute);
14672
28.1k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel18.7k
) {
14673
18.7k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14674
    // 1.2.2 OpenMP Language Terminology
14675
    // Structured block - An executable statement with a single entry at the
14676
    // top and a single exit at the bottom.
14677
    // The point of exit cannot be a branch out of the structured block.
14678
    // longjmp() and throw() must not violate the entry/exit criteria.
14679
18.7k
    CS->getCapturedDecl()->setNothrow();
14680
18.7k
  }
14681
14682
9.39k
  OMPLoopBasedDirective::HelperExprs B;
14683
  // In presence of clause 'collapse' with number of loops, it will
14684
  // define the nested loops number.
14685
9.39k
  unsigned NestedLoopCount = checkOpenMPLoop(
14686
9.39k
      OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
14687
9.39k
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14688
9.39k
      VarsWithImplicitDSA, B);
14689
9.39k
  if (NestedLoopCount == 0)
14690
274
    return StmtError();
14691
14692
9.12k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14693
9.12k
         "omp target teams distribute loop exprs were not built");
14694
14695
9.12k
  setFunctionHasBranchProtectedScope();
14696
9.12k
  return OMPTargetTeamsDistributeDirective::Create(
14697
9.12k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14698
9.12k
}
14699
14700
StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
14701
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14702
9.46k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14703
9.46k
  if (!AStmt)
14704
0
    return StmtError();
14705
14706
9.46k
  auto *CS = cast<CapturedStmt>(AStmt);
14707
  // 1.2.2 OpenMP Language Terminology
14708
  // Structured block - An executable statement with a single entry at the
14709
  // top and a single exit at the bottom.
14710
  // The point of exit cannot be a branch out of the structured block.
14711
  // longjmp() and throw() must not violate the entry/exit criteria.
14712
9.46k
  CS->getCapturedDecl()->setNothrow();
14713
9.46k
  for (int ThisCaptureLevel =
14714
9.46k
           getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
14715
37.8k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel28.4k
) {
14716
28.4k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14717
    // 1.2.2 OpenMP Language Terminology
14718
    // Structured block - An executable statement with a single entry at the
14719
    // top and a single exit at the bottom.
14720
    // The point of exit cannot be a branch out of the structured block.
14721
    // longjmp() and throw() must not violate the entry/exit criteria.
14722
28.4k
    CS->getCapturedDecl()->setNothrow();
14723
28.4k
  }
14724
14725
9.46k
  OMPLoopBasedDirective::HelperExprs B;
14726
  // In presence of clause 'collapse' with number of loops, it will
14727
  // define the nested loops number.
14728
9.46k
  unsigned NestedLoopCount = checkOpenMPLoop(
14729
9.46k
      OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14730
9.46k
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14731
9.46k
      VarsWithImplicitDSA, B);
14732
9.46k
  if (NestedLoopCount == 0)
14733
272
    return StmtError();
14734
14735
9.19k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14736
9.19k
         "omp target teams distribute parallel for loop exprs were not built");
14737
14738
9.19k
  if (!CurContext->isDependentContext()) {
14739
    // Finalize the clauses that need pre-built expressions for CodeGen.
14740
6.63k
    for (OMPClause *C : Clauses) {
14741
6.63k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14742
0
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14743
0
                                     B.NumIterations, *this, CurScope,
14744
0
                                     DSAStack))
14745
0
          return StmtError();
14746
6.63k
    }
14747
6.63k
  }
14748
14749
9.19k
  setFunctionHasBranchProtectedScope();
14750
9.19k
  return OMPTargetTeamsDistributeParallelForDirective::Create(
14751
9.19k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14752
9.19k
      DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14753
9.19k
}
14754
14755
StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
14756
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14757
11.8k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14758
11.8k
  if (!AStmt)
14759
4
    return StmtError();
14760
14761
11.8k
  auto *CS = cast<CapturedStmt>(AStmt);
14762
  // 1.2.2 OpenMP Language Terminology
14763
  // Structured block - An executable statement with a single entry at the
14764
  // top and a single exit at the bottom.
14765
  // The point of exit cannot be a branch out of the structured block.
14766
  // longjmp() and throw() must not violate the entry/exit criteria.
14767
11.8k
  CS->getCapturedDecl()->setNothrow();
14768
11.8k
  for (int ThisCaptureLevel = getOpenMPCaptureLevels(
14769
11.8k
           OMPD_target_teams_distribute_parallel_for_simd);
14770
47.2k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel35.4k
) {
14771
35.4k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14772
    // 1.2.2 OpenMP Language Terminology
14773
    // Structured block - An executable statement with a single entry at the
14774
    // top and a single exit at the bottom.
14775
    // The point of exit cannot be a branch out of the structured block.
14776
    // longjmp() and throw() must not violate the entry/exit criteria.
14777
35.4k
    CS->getCapturedDecl()->setNothrow();
14778
35.4k
  }
14779
14780
11.8k
  OMPLoopBasedDirective::HelperExprs B;
14781
  // In presence of clause 'collapse' with number of loops, it will
14782
  // define the nested loops number.
14783
11.8k
  unsigned NestedLoopCount =
14784
11.8k
      checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
14785
11.8k
                      getCollapseNumberExpr(Clauses),
14786
11.8k
                      nullptr /*ordered not a clause on distribute*/, CS, *this,
14787
11.8k
                      *DSAStack, VarsWithImplicitDSA, B);
14788
11.8k
  if (NestedLoopCount == 0)
14789
406
    return StmtError();
14790
14791
11.4k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14792
11.4k
         "omp target teams distribute parallel for simd loop exprs were not "
14793
11.4k
         "built");
14794
14795
11.4k
  if (!CurContext->isDependentContext()) {
14796
    // Finalize the clauses that need pre-built expressions for CodeGen.
14797
8.93k
    for (OMPClause *C : Clauses) {
14798
8.93k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14799
96
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14800
96
                                     B.NumIterations, *this, CurScope,
14801
96
                                     DSAStack))
14802
72
          return StmtError();
14803
8.93k
    }
14804
8.33k
  }
14805
14806
11.3k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14807
4
    return StmtError();
14808
14809
11.3k
  setFunctionHasBranchProtectedScope();
14810
11.3k
  return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
14811
11.3k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14812
11.3k
}
14813
14814
StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14815
    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14816
11.1k
    SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14817
11.1k
  if (!AStmt)
14818
6
    return StmtError();
14819
14820
11.1k
  auto *CS = cast<CapturedStmt>(AStmt);
14821
  // 1.2.2 OpenMP Language Terminology
14822
  // Structured block - An executable statement with a single entry at the
14823
  // top and a single exit at the bottom.
14824
  // The point of exit cannot be a branch out of the structured block.
14825
  // longjmp() and throw() must not violate the entry/exit criteria.
14826
11.1k
  CS->getCapturedDecl()->setNothrow();
14827
11.1k
  for (int ThisCaptureLevel =
14828
11.1k
           getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
14829
33.5k
       ThisCaptureLevel > 1; 
--ThisCaptureLevel22.3k
) {
14830
22.3k
    CS = cast<CapturedStmt>(CS->getCapturedStmt());
14831
    // 1.2.2 OpenMP Language Terminology
14832
    // Structured block - An executable statement with a single entry at the
14833
    // top and a single exit at the bottom.
14834
    // The point of exit cannot be a branch out of the structured block.
14835
    // longjmp() and throw() must not violate the entry/exit criteria.
14836
22.3k
    CS->getCapturedDecl()->setNothrow();
14837
22.3k
  }
14838
14839
11.1k
  OMPLoopBasedDirective::HelperExprs B;
14840
  // In presence of clause 'collapse' with number of loops, it will
14841
  // define the nested loops number.
14842
11.1k
  unsigned NestedLoopCount = checkOpenMPLoop(
14843
11.1k
      OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14844
11.1k
      nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14845
11.1k
      VarsWithImplicitDSA, B);
14846
11.1k
  if (NestedLoopCount == 0)
14847
318
    return StmtError();
14848
14849
10.8k
  assert((CurContext->isDependentContext() || B.builtAll()) &&
14850
10.8k
         "omp target teams distribute simd loop exprs were not built");
14851
14852
10.8k
  if (!CurContext->isDependentContext()) {
14853
    // Finalize the clauses that need pre-built expressions for CodeGen.
14854
8.82k
    for (OMPClause *C : Clauses) {
14855
8.82k
      if (auto *LC = dyn_cast<OMPLinearClause>(C))
14856
116
        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14857
116
                                     B.NumIterations, *this, CurScope,
14858
116
                                     DSAStack))
14859
72
          return StmtError();
14860
8.82k
    }
14861
8.01k
  }
14862
14863
10.7k
  if (checkSimdlenSafelenSpecified(*this, Clauses))
14864
6
    return StmtError();
14865
14866
10.7k
  setFunctionHasBranchProtectedScope();
14867
10.7k
  return OMPTargetTeamsDistributeSimdDirective::Create(
14868
10.7k
      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14869
10.7k
}
14870
14871
bool Sema::checkTransformableLoopNest(
14872
    OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
14873
    SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14874
    Stmt *&Body,
14875
    SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
14876
181
        &OriginalInits) {
14877
181
  OriginalInits.emplace_back();
14878
181
  bool Result = OMPLoopBasedDirective::doForAllLoops(
14879
181
      AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
14880
181
      [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
14881
204
                                                        Stmt *CurStmt) {
14882
204
        VarsWithInheritedDSAType TmpDSA;
14883
204
        unsigned SingleNumLoops =
14884
204
            checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
14885
204
                            TmpDSA, LoopHelpers[Cnt]);
14886
204
        if (SingleNumLoops == 0)
14887
10
          return true;
14888
194
        assert(SingleNumLoops == 1 && "Expect single loop iteration space");
14889
194
        if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14890
194
          OriginalInits.back().push_back(For->getInit());
14891
194
          Body = For->getBody();
14892
194
        } else {
14893
0
          assert(isa<CXXForRangeStmt>(CurStmt) &&
14894
0
                 "Expected canonical for or range-based for loops.");
14895
0
          auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14896
0
          OriginalInits.back().push_back(CXXFor->getBeginStmt());
14897
0
          Body = CXXFor->getBody();
14898
0
        }
14899
194
        OriginalInits.emplace_back();
14900
194
        return false;
14901
194
      },
14902
181
      [&OriginalInits](OMPLoopBasedDirective *Transform) {
14903
11
        Stmt *DependentPreInits;
14904
11
        if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14905
2
          DependentPreInits = Dir->getPreInits();
14906
9
        else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14907
9
          DependentPreInits = Dir->getPreInits();
14908
0
        else
14909
0
          llvm_unreachable("Unhandled loop transformation");
14910
11
        if (!DependentPreInits)
14911
2
          return;
14912
9
        llvm::append_range(OriginalInits.back(),
14913
9
                           cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14914
9
      });
14915
181
  assert(OriginalInits.back().empty() && "No preinit after innermost loop");
14916
181
  OriginalInits.pop_back();
14917
181
  return Result;
14918
181
}
14919
14920
StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
14921
                                          Stmt *AStmt, SourceLocation StartLoc,
14922
90
                                          SourceLocation EndLoc) {
14923
90
  auto SizesClauses =
14924
90
      OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14925
90
  if (SizesClauses.empty()) {
14926
    // A missing 'sizes' clause is already reported by the parser.
14927
11
    return StmtError();
14928
11
  }
14929
79
  const OMPSizesClause *SizesClause = *SizesClauses.begin();
14930
79
  unsigned NumLoops = SizesClause->getNumSizes();
14931
14932
  // Empty statement should only be possible if there already was an error.
14933
79
  if (!AStmt)
14934
1
    return StmtError();
14935
14936
  // Verify and diagnose loop nest.
14937
78
  SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14938
78
  Stmt *Body = nullptr;
14939
78
  SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
14940
78
      OriginalInits;
14941
78
  if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14942
78
                                  OriginalInits))
14943
6
    return StmtError();
14944
14945
  // Delay tiling to when template is completely instantiated.
14946
72
  if (CurContext->isDependentContext())
14947
10
    return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14948
10
                                    NumLoops, AStmt, nullptr, nullptr);
14949
14950
62
  SmallVector<Decl *, 4> PreInits;
14951
14952
  // Create iteration variables for the generated loops.
14953
62
  SmallVector<VarDecl *, 4> FloorIndVars;
14954
62
  SmallVector<VarDecl *, 4> TileIndVars;
14955
62
  FloorIndVars.resize(NumLoops);
14956
62
  TileIndVars.resize(NumLoops);
14957
145
  for (unsigned I = 0; I < NumLoops; 
++I83
) {
14958
83
    OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14959
14960
83
    assert(LoopHelper.Counters.size() == 1 &&
14961
83
           "Expect single-dimensional loop iteration space");
14962
83
    auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14963
83
    std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14964
83
    DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14965
83
    QualType CntTy = IterVarRef->getType();
14966
14967
    // Iteration variable for the floor (i.e. outer) loop.
14968
83
    {
14969
83
      std::string FloorCntName =
14970
83
          (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14971
83
      VarDecl *FloorCntDecl =
14972
83
          buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
14973
83
      FloorIndVars[I] = FloorCntDecl;
14974
83
    }
14975
14976
    // Iteration variable for the tile (i.e. inner) loop.
14977
83
    {
14978
83
      std::string TileCntName =
14979
83
          (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14980
14981
      // Reuse the iteration variable created by checkOpenMPLoop. It is also
14982
      // used by the expressions to derive the original iteration variable's
14983
      // value from the logical iteration number.
14984
83
      auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
14985
83
      TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
14986
83
      TileIndVars[I] = TileCntDecl;
14987
83
    }
14988
103
    for (auto &P : OriginalInits[I]) {
14989
103
      if (auto *D = P.dyn_cast<Decl *>())
14990
20
        PreInits.push_back(D);
14991
83
      else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14992
79
        PreInits.append(PI->decl_begin(), PI->decl_end());
14993
103
    }
14994
83
    if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14995
33
      PreInits.append(PI->decl_begin(), PI->decl_end());
14996
    // Gather declarations for the data members used as counters.
14997
83
    for (Expr *CounterRef : LoopHelper.Counters) {
14998
83
      auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14999
83
      if (isa<OMPCapturedExprDecl>(CounterDecl))
15000
2
        PreInits.push_back(CounterDecl);
15001
83
    }
15002
83
  }
15003
15004
  // Once the original iteration values are set, append the innermost body.
15005
62
  Stmt *Inner = Body;
15006
15007
  // Create tile loops from the inside to the outside.
15008
145
  for (int I = NumLoops - 1; I >= 0; 
--I83
) {
15009
83
    OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
15010
83
    Expr *NumIterations = LoopHelper.NumIterations;
15011
83
    auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15012
83
    QualType CntTy = OrigCntVar->getType();
15013
83
    Expr *DimTileSize = SizesClause->getSizesRefs()[I];
15014
83
    Scope *CurScope = getCurScope();
15015
15016
    // Commonly used variables.
15017
83
    DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
15018
83
                                           OrigCntVar->getExprLoc());
15019
83
    DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
15020
83
                                            OrigCntVar->getExprLoc());
15021
15022
    // For init-statement: auto .tile.iv = .floor.iv
15023
83
    AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
15024
83
                         /*DirectInit=*/false);
15025
83
    Decl *CounterDecl = TileIndVars[I];
15026
83
    StmtResult InitStmt = new (Context)
15027
83
        DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
15028
83
                 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15029
83
    if (!InitStmt.isUsable())
15030
0
      return StmtError();
15031
15032
    // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
15033
    // NumIterations)
15034
83
    ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15035
83
                                      BO_Add, FloorIV, DimTileSize);
15036
83
    if (!EndOfTile.isUsable())
15037
0
      return StmtError();
15038
83
    ExprResult IsPartialTile =
15039
83
        BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
15040
83
                   NumIterations, EndOfTile.get());
15041
83
    if (!IsPartialTile.isUsable())
15042
0
      return StmtError();
15043
83
    ExprResult MinTileAndIterSpace = ActOnConditionalOp(
15044
83
        LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
15045
83
        IsPartialTile.get(), NumIterations, EndOfTile.get());
15046
83
    if (!MinTileAndIterSpace.isUsable())
15047
0
      return StmtError();
15048
83
    ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15049
83
                                     BO_LT, TileIV, MinTileAndIterSpace.get());
15050
83
    if (!CondExpr.isUsable())
15051
0
      return StmtError();
15052
15053
    // For incr-statement: ++.tile.iv
15054
83
    ExprResult IncrStmt =
15055
83
        BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
15056
83
    if (!IncrStmt.isUsable())
15057
0
      return StmtError();
15058
15059
    // Statements to set the original iteration variable's value from the
15060
    // logical iteration number.
15061
    // Generated for loop is:
15062
    // Original_for_init;
15063
    // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
15064
    // NumIterations); ++.tile.iv) {
15065
    //   Original_Body;
15066
    //   Original_counter_update;
15067
    // }
15068
    // FIXME: If the innermost body is an loop itself, inserting these
15069
    // statements stops it being recognized  as a perfectly nested loop (e.g.
15070
    // for applying tiling again). If this is the case, sink the expressions
15071
    // further into the inner loop.
15072
83
    SmallVector<Stmt *, 4> BodyParts;
15073
83
    BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15074
83
    BodyParts.push_back(Inner);
15075
83
    Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
15076
83
                                 Inner->getBeginLoc(), Inner->getEndLoc());
15077
83
    Inner = new (Context)
15078
83
        ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
15079
83
                IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
15080
83
                LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15081
83
  }
15082
15083
  // Create floor loops from the inside to the outside.
15084
145
  
for (int I = NumLoops - 1; 62
I >= 0;
--I83
) {
15085
83
    auto &LoopHelper = LoopHelpers[I];
15086
83
    Expr *NumIterations = LoopHelper.NumIterations;
15087
83
    DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15088
83
    QualType CntTy = OrigCntVar->getType();
15089
83
    Expr *DimTileSize = SizesClause->getSizesRefs()[I];
15090
83
    Scope *CurScope = getCurScope();
15091
15092
    // Commonly used variables.
15093
83
    DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
15094
83
                                            OrigCntVar->getExprLoc());
15095
15096
    // For init-statement: auto .floor.iv = 0
15097
83
    AddInitializerToDecl(
15098
83
        FloorIndVars[I],
15099
83
        ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15100
83
        /*DirectInit=*/false);
15101
83
    Decl *CounterDecl = FloorIndVars[I];
15102
83
    StmtResult InitStmt = new (Context)
15103
83
        DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
15104
83
                 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15105
83
    if (!InitStmt.isUsable())
15106
0
      return StmtError();
15107
15108
    // For cond-expression: .floor.iv < NumIterations
15109
83
    ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15110
83
                                     BO_LT, FloorIV, NumIterations);
15111
83
    if (!CondExpr.isUsable())
15112
0
      return StmtError();
15113
15114
    // For incr-statement: .floor.iv += DimTileSize
15115
83
    ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
15116
83
                                     BO_AddAssign, FloorIV, DimTileSize);
15117
83
    if (!IncrStmt.isUsable())
15118
0
      return StmtError();
15119
15120
83
    Inner = new (Context)
15121
83
        ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
15122
83
                IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
15123
83
                LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15124
83
  }
15125
15126
62
  return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
15127
62
                                  AStmt, Inner,
15128
62
                                  buildPreInits(Context, PreInits));
15129
62
}
15130
15131
StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
15132
                                            Stmt *AStmt,
15133
                                            SourceLocation StartLoc,
15134
105
                                            SourceLocation EndLoc) {
15135
  // Empty statement should only be possible if there already was an error.
15136
105
  if (!AStmt)
15137
0
    return StmtError();
15138
15139
105
  if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
15140
2
    return StmtError();
15141
15142
103
  const OMPFullClause *FullClause =
15143
103
      OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
15144
103
  const OMPPartialClause *PartialClause =
15145
103
      OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
15146
103
  assert(!(FullClause && PartialClause) &&
15147
103
         "mutual exclusivity must have been checked before");
15148
15149
103
  constexpr unsigned NumLoops = 1;
15150
103
  Stmt *Body = nullptr;
15151
103
  SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
15152
103
      NumLoops);
15153
103
  SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
15154
103
      OriginalInits;
15155
103
  if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
15156
103
                                  Body, OriginalInits))
15157
4
    return StmtError();
15158
15159
99
  unsigned NumGeneratedLoops = PartialClause ? 
165
:
034
;
15160
15161
  // Delay unrolling to when template is completely instantiated.
15162
99
  if (CurContext->isDependentContext())
15163
10
    return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15164
10
                                      NumGeneratedLoops, nullptr, nullptr);
15165
15166
89
  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
15167
15168
89
  if (FullClause) {
15169
12
    if (!VerifyPositiveIntegerConstantInClause(
15170
12
             LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
15171
12
             /*SuppressExprDiags=*/true)
15172
12
             .isUsable()) {
15173
2
      Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
15174
2
      Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
15175
2
          << "#pragma omp unroll full";
15176
2
      return StmtError();
15177
2
    }
15178
12
  }
15179
15180
  // The generated loop may only be passed to other loop-associated directive
15181
  // when a partial clause is specified. Without the requirement it is
15182
  // sufficient to generate loop unroll metadata at code-generation.
15183
87
  if (NumGeneratedLoops == 0)
15184
31
    return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15185
31
                                      NumGeneratedLoops, nullptr, nullptr);
15186
15187
  // Otherwise, we need to provide a de-sugared/transformed AST that can be
15188
  // associated with another loop directive.
15189
  //
15190
  // The canonical loop analysis return by checkTransformableLoopNest assumes
15191
  // the following structure to be the same loop without transformations or
15192
  // directives applied: \code OriginalInits; LoopHelper.PreInits;
15193
  // LoopHelper.Counters;
15194
  // for (; IV < LoopHelper.NumIterations; ++IV) {
15195
  //   LoopHelper.Updates;
15196
  //   Body;
15197
  // }
15198
  // \endcode
15199
  // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
15200
  // and referenced by LoopHelper.IterationVarRef.
15201
  //
15202
  // The unrolling directive transforms this into the following loop:
15203
  // \code
15204
  // OriginalInits;         \
15205
  // LoopHelper.PreInits;    > NewPreInits
15206
  // LoopHelper.Counters;   /
15207
  // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
15208
  //   #pragma clang loop unroll_count(Factor)
15209
  //   for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
15210
  //   {
15211
  //     LoopHelper.Updates;
15212
  //     Body;
15213
  //   }
15214
  // }
15215
  // \endcode
15216
  // where UIV is a new logical iteration counter. IV must be the same VarDecl
15217
  // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
15218
  // references it. If the partially unrolled loop is associated with another
15219
  // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
15220
  // analyze this loop, i.e. the outer loop must fulfill the constraints of an
15221
  // OpenMP canonical loop. The inner loop is not an associable canonical loop
15222
  // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
15223
  // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
15224
  // property of the OMPLoopBasedDirective instead of statements in
15225
  // CompoundStatement. This is to allow the loop to become a non-outermost loop
15226
  // of a canonical loop nest where these PreInits are emitted before the
15227
  // outermost directive.
15228
15229
  // Determine the PreInit declarations.
15230
56
  SmallVector<Decl *, 4> PreInits;
15231
56
  assert(OriginalInits.size() == 1 &&
15232
56
         "Expecting a single-dimensional loop iteration space");
15233
77
  
for (auto &P : OriginalInits[0])56
{
15234
77
    if (auto *D = P.dyn_cast<Decl *>())
15235
21
      PreInits.push_back(D);
15236
56
    else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
15237
54
      PreInits.append(PI->decl_begin(), PI->decl_end());
15238
77
  }
15239
56
  if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
15240
31
    PreInits.append(PI->decl_begin(), PI->decl_end());
15241
  // Gather declarations for the data members used as counters.
15242
56
  for (Expr *CounterRef : LoopHelper.Counters) {
15243
56
    auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15244
56
    if (isa<OMPCapturedExprDecl>(CounterDecl))
15245
0
      PreInits.push_back(CounterDecl);
15246
56
  }
15247
15248
56
  auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
15249
56
  QualType IVTy = IterationVarRef->getType();
15250
56
  assert(LoopHelper.Counters.size() == 1 &&
15251
56
         "Expecting a single-dimensional loop iteration space");
15252
56
  auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
15253
15254
  // Determine the unroll factor.
15255
56
  uint64_t Factor;
15256
56
  SourceLocation FactorLoc;
15257
56
  if (Expr *FactorVal = PartialClause->getFactor()) {
15258
29
    Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
15259
29
    FactorLoc = FactorVal->getExprLoc();
15260
29
  } else {
15261
    // TODO: Use a better profitability model.
15262
27
    Factor = 2;
15263
27
  }
15264
56
  assert(Factor > 0 && "Expected positive unroll factor");
15265
168
  
auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() 56
{
15266
168
    return IntegerLiteral::Create(
15267
168
        Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
15268
168
        FactorLoc);
15269
168
  };
15270
15271
  // Iteration variable SourceLocations.
15272
56
  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
15273
56
  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
15274
56
  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
15275
15276
  // Internal variable names.
15277
56
  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
15278
56
  std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
15279
56
  std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
15280
56
  std::string InnerTripCountName =
15281
56
      (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
15282
15283
  // Create the iteration variable for the unrolled loop.
15284
56
  VarDecl *OuterIVDecl =
15285
56
      buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
15286
224
  auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
15287
224
    return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
15288
224
  };
15289
15290
  // Iteration variable for the inner loop: Reuse the iteration variable created
15291
  // by checkOpenMPLoop.
15292
56
  auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15293
56
  InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
15294
168
  auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
15295
168
    return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
15296
168
  };
15297
15298
  // Make a copy of the NumIterations expression for each use: By the AST
15299
  // constraints, every expression object in a DeclContext must be unique.
15300
56
  CaptureVars CopyTransformer(*this);
15301
112
  auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
15302
112
    return AssertSuccess(
15303
112
        CopyTransformer.TransformExpr(LoopHelper.NumIterations));
15304
112
  };
15305
15306
  // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
15307
56
  ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
15308
56
  AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
15309
56
  StmtResult InnerInit = new (Context)
15310
56
      DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15311
56
  if (!InnerInit.isUsable())
15312
0
    return StmtError();
15313
15314
  // Inner For cond-expression:
15315
  // \code
15316
  //   .unroll_inner.iv < .unrolled.iv + Factor &&
15317
  //   .unroll_inner.iv < NumIterations
15318
  // \endcode
15319
  // This conjunction of two conditions allows ScalarEvolution to derive the
15320
  // maximum trip count of the inner loop.
15321
56
  ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15322
56
                                    BO_Add, MakeOuterRef(), MakeFactorExpr());
15323
56
  if (!EndOfTile.isUsable())
15324
0
    return StmtError();
15325
56
  ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15326
56
                                     BO_LT, MakeInnerRef(), EndOfTile.get());
15327
56
  if (!InnerCond1.isUsable())
15328
0
    return StmtError();
15329
56
  ExprResult InnerCond2 =
15330
56
      BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
15331
56
                 MakeNumIterations());
15332
56
  if (!InnerCond2.isUsable())
15333
0
    return StmtError();
15334
56
  ExprResult InnerCond =
15335
56
      BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
15336
56
                 InnerCond1.get(), InnerCond2.get());
15337
56
  if (!InnerCond.isUsable())
15338
0
    return StmtError();
15339
15340
  // Inner For incr-statement: ++.unroll_inner.iv
15341
56
  ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
15342
56
                                      UO_PreInc, MakeInnerRef());
15343
56
  if (!InnerIncr.isUsable())
15344
0
    return StmtError();
15345
15346
  // Inner For statement.
15347
56
  SmallVector<Stmt *> InnerBodyStmts;
15348
56
  InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15349
56
  InnerBodyStmts.push_back(Body);
15350
56
  CompoundStmt *InnerBody =
15351
56
      CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(),
15352
56
                           Body->getBeginLoc(), Body->getEndLoc());
15353
56
  ForStmt *InnerFor = new (Context)
15354
56
      ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
15355
56
              InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
15356
56
              LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15357
15358
  // Unroll metadata for the inner loop.
15359
  // This needs to take into account the remainder portion of the unrolled loop,
15360
  // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
15361
  // supports multiple loop exits. Instead, unroll using a factor equivalent to
15362
  // the maximum trip count, which will also generate a remainder loop. Just
15363
  // `unroll(enable)` (which could have been useful if the user has not
15364
  // specified a concrete factor; even though the outer loop cannot be
15365
  // influenced anymore, would avoid more code bloat than necessary) will refuse
15366
  // the loop because "Won't unroll; remainder loop could not be generated when
15367
  // assuming runtime trip count". Even if it did work, it must not choose a
15368
  // larger unroll factor than the maximum loop length, or it would always just
15369
  // execute the remainder loop.
15370
56
  LoopHintAttr *UnrollHintAttr =
15371
56
      LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
15372
56
                                   LoopHintAttr::Numeric, MakeFactorExpr());
15373
56
  AttributedStmt *InnerUnrolled =
15374
56
      AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
15375
15376
  // Outer For init-statement: auto .unrolled.iv = 0
15377
56
  AddInitializerToDecl(
15378
56
      OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15379
56
      /*DirectInit=*/false);
15380
56
  StmtResult OuterInit = new (Context)
15381
56
      DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15382
56
  if (!OuterInit.isUsable())
15383
0
    return StmtError();
15384
15385
  // Outer For cond-expression: .unrolled.iv < NumIterations
15386
56
  ExprResult OuterConde =
15387
56
      BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
15388
56
                 MakeNumIterations());
15389
56
  if (!OuterConde.isUsable())
15390
0
    return StmtError();
15391
15392
  // Outer For incr-statement: .unrolled.iv += Factor
15393
56
  ExprResult OuterIncr =
15394
56
      BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
15395
56
                 MakeOuterRef(), MakeFactorExpr());
15396
56
  if (!OuterIncr.isUsable())
15397
0
    return StmtError();
15398
15399
  // Outer For statement.
15400
56
  ForStmt *OuterFor = new (Context)
15401
56
      ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
15402
56
              OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
15403
56
              LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15404
15405
56
  return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15406
56
                                    NumGeneratedLoops, OuterFor,
15407
56
                                    buildPreInits(Context, PreInits));
15408
56
}
15409
15410
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
15411
                                             SourceLocation StartLoc,
15412
                                             SourceLocation LParenLoc,
15413
20.2k
                                             SourceLocation EndLoc) {
15414
20.2k
  OMPClause *Res = nullptr;
15415
20.2k
  switch (Kind) {
15416
537
  case OMPC_final:
15417
537
    Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
15418
537
    break;
15419
1.37k
  case OMPC_num_threads:
15420
1.37k
    Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
15421
1.37k
    break;
15422
3.58k
  case OMPC_safelen:
15423
3.58k
    Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
15424
3.58k
    break;
15425
2.49k
  case OMPC_simdlen:
15426
2.49k
    Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
15427
2.49k
    break;
15428
409
  case OMPC_allocator:
15429
409
    Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
15430
409
    break;
15431
6.16k
  case OMPC_collapse:
15432
6.16k
    Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
15433
6.16k
    break;
15434
645
  case OMPC_ordered:
15435
645
    Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
15436
645
    break;
15437
1.54k
  case OMPC_num_teams:
15438
1.54k
    Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
15439
1.54k
    break;
15440
1.32k
  case OMPC_thread_limit:
15441
1.32k
    Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
15442
1.32k
    break;
15443
662
  case OMPC_priority:
15444
662
    Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
15445
662
    break;
15446
208
  case OMPC_hint:
15447
208
    Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
15448
208
    break;
15449
416
  case OMPC_depobj:
15450
416
    Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
15451
416
    break;
15452
101
  case OMPC_detach:
15453
101
    Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
15454
101
    break;
15455
16
  case OMPC_novariants:
15456
16
    Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
15457
16
    break;
15458
16
  case OMPC_nocontext:
15459
16
    Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
15460
16
    break;
15461
289
  case OMPC_filter:
15462
289
    Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
15463
289
    break;
15464
31
  case OMPC_partial:
15465
31
    Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
15466
31
    break;
15467
54
  case OMPC_message:
15468
54
    Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
15469
54
    break;
15470
75
  case OMPC_align:
15471
75
    Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
15472
75
    break;
15473
304
  case OMPC_ompx_dyn_cgroup_mem:
15474
304
    Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc);
15475
304
    break;
15476
0
  case OMPC_grainsize:
15477
0
  case OMPC_num_tasks:
15478
0
  case OMPC_device:
15479
0
  case OMPC_if:
15480
0
  case OMPC_default:
15481
0
  case OMPC_proc_bind:
15482
0
  case OMPC_schedule:
15483
0
  case OMPC_private:
15484
0
  case OMPC_firstprivate:
15485
0
  case OMPC_lastprivate:
15486
0
  case OMPC_shared:
15487
0
  case OMPC_reduction:
15488
0
  case OMPC_task_reduction:
15489
0
  case OMPC_in_reduction:
15490
0
  case OMPC_linear:
15491
0
  case OMPC_aligned:
15492
0
  case OMPC_copyin:
15493
0
  case OMPC_copyprivate:
15494
0
  case OMPC_nowait:
15495
0
  case OMPC_untied:
15496
0
  case OMPC_mergeable:
15497
0
  case OMPC_threadprivate:
15498
0
  case OMPC_sizes:
15499
0
  case OMPC_allocate:
15500
0
  case OMPC_flush:
15501
0
  case OMPC_read:
15502
0
  case OMPC_write:
15503
0
  case OMPC_update:
15504
0
  case OMPC_capture:
15505
0
  case OMPC_compare:
15506
0
  case OMPC_seq_cst:
15507
0
  case OMPC_acq_rel:
15508
0
  case OMPC_acquire:
15509
0
  case OMPC_release:
15510
0
  case OMPC_relaxed:
15511
0
  case OMPC_depend:
15512
0
  case OMPC_threads:
15513
0
  case OMPC_simd:
15514
0
  case OMPC_map:
15515
0
  case OMPC_nogroup:
15516
0
  case OMPC_dist_schedule:
15517
0
  case OMPC_defaultmap:
15518
0
  case OMPC_unknown:
15519
0
  case OMPC_uniform:
15520
0
  case OMPC_to:
15521
0
  case OMPC_from:
15522
0
  case OMPC_use_device_ptr:
15523
0
  case OMPC_use_device_addr:
15524
0
  case OMPC_is_device_ptr:
15525
0
  case OMPC_unified_address:
15526
0
  case OMPC_unified_shared_memory:
15527
0
  case OMPC_reverse_offload:
15528
0
  case OMPC_dynamic_allocators:
15529
0
  case OMPC_atomic_default_mem_order:
15530
0
  case OMPC_device_type:
15531
0
  case OMPC_match:
15532
0
  case OMPC_nontemporal:
15533
0
  case OMPC_order:
15534
0
  case OMPC_at:
15535
0
  case OMPC_severity:
15536
0
  case OMPC_destroy:
15537
0
  case OMPC_inclusive:
15538
0
  case OMPC_exclusive:
15539
0
  case OMPC_uses_allocators:
15540
0
  case OMPC_affinity:
15541
0
  case OMPC_when:
15542
0
  case OMPC_bind:
15543
0
  default:
15544
0
    llvm_unreachable("Clause is not allowed.");
15545
20.2k
  }
15546
20.2k
  return Res;
15547
20.2k
}
15548
15549
// An OpenMP directive such as 'target parallel' has two captured regions:
15550
// for the 'target' and 'parallel' respectively.  This function returns
15551
// the region in which to capture expressions associated with a clause.
15552
// A return value of OMPD_unknown signifies that the expression should not
15553
// be captured.
15554
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
15555
    OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
15556
23.3k
    OpenMPDirectiveKind NameModifier = OMPD_unknown) {
15557
23.3k
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15558
23.3k
  switch (CKind) {
15559
10.8k
  case OMPC_if:
15560
10.8k
    switch (DKind) {
15561
765
    case OMPD_target_parallel_for_simd:
15562
765
      if (OpenMPVersion >= 50 &&
15563
765
          
(440
NameModifier == OMPD_unknown440
||
NameModifier == OMPD_simd326
)) {
15564
134
        CaptureRegion = OMPD_parallel;
15565
134
        break;
15566
134
      }
15567
765
      
[[fallthrough]];631
15568
1.65k
    case OMPD_target_parallel:
15569
2.34k
    case OMPD_target_parallel_for:
15570
2.43k
    case OMPD_target_parallel_loop:
15571
      // If this clause applies to the nested 'parallel' region, capture within
15572
      // the 'target' region, otherwise do not capture.
15573
2.43k
      if (NameModifier == OMPD_unknown || 
NameModifier == OMPD_parallel2.04k
)
15574
905
        CaptureRegion = OMPD_target;
15575
2.43k
      break;
15576
428
    case OMPD_target_teams_distribute_parallel_for_simd:
15577
428
      if (OpenMPVersion >= 50 &&
15578
428
          
(227
NameModifier == OMPD_unknown227
||
NameModifier == OMPD_simd122
)) {
15579
117
        CaptureRegion = OMPD_parallel;
15580
117
        break;
15581
117
      }
15582
428
      
[[fallthrough]];311
15583
524
    case OMPD_target_teams_loop:
15584
859
    case OMPD_target_teams_distribute_parallel_for:
15585
      // If this clause applies to the nested 'parallel' region, capture within
15586
      // the 'teams' region, otherwise do not capture.
15587
859
      if (NameModifier == OMPD_unknown || 
NameModifier == OMPD_parallel413
)
15588
598
        CaptureRegion = OMPD_teams;
15589
859
      break;
15590
257
    case OMPD_teams_distribute_parallel_for_simd:
15591
257
      if (OpenMPVersion >= 50 &&
15592
257
          
(130
NameModifier == OMPD_unknown130
||
NameModifier == OMPD_simd40
)) {
15593
94
        CaptureRegion = OMPD_parallel;
15594
94
        break;
15595
94
      }
15596
257
      
[[fallthrough]];163
15597
416
    case OMPD_teams_distribute_parallel_for:
15598
416
      CaptureRegion = OMPD_teams;
15599
416
      break;
15600
251
    case OMPD_target_update:
15601
679
    case OMPD_target_enter_data:
15602
1.08k
    case OMPD_target_exit_data:
15603
1.08k
      CaptureRegion = OMPD_task;
15604
1.08k
      break;
15605
37
    case OMPD_parallel_masked_taskloop:
15606
37
      if (NameModifier == OMPD_unknown || 
NameModifier == OMPD_taskloop20
)
15607
29
        CaptureRegion = OMPD_parallel;
15608
37
      break;
15609
40
    case OMPD_parallel_master_taskloop:
15610
40
      if (NameModifier == OMPD_unknown || 
NameModifier == OMPD_taskloop20
)
15611
32
        CaptureRegion = OMPD_parallel;
15612
40
      break;
15613
37
    case OMPD_parallel_masked_taskloop_simd:
15614
37
      if ((OpenMPVersion <= 45 && 
NameModifier == OMPD_unknown7
) ||
15615
37
          
NameModifier == OMPD_taskloop34
) {
15616
15
        CaptureRegion = OMPD_parallel;
15617
15
        break;
15618
15
      }
15619
22
      if (OpenMPVersion <= 45)
15620
2
        break;
15621
20
      if (NameModifier == OMPD_unknown || 
NameModifier == OMPD_simd10
)
15622
14
        CaptureRegion = OMPD_taskloop;
15623
20
      break;
15624
68
    case OMPD_parallel_master_taskloop_simd:
15625
68
      if ((OpenMPVersion <= 45 && 
NameModifier == OMPD_unknown10
) ||
15626
68
          
NameModifier == OMPD_taskloop62
) {
15627
26
        CaptureRegion = OMPD_parallel;
15628
26
        break;
15629
26
      }
15630
42
      if (OpenMPVersion <= 45)
15631
2
        break;
15632
40
      if (NameModifier == OMPD_unknown || 
NameModifier == OMPD_simd18
)
15633
30
        CaptureRegion = OMPD_taskloop;
15634
40
      break;
15635
109
    case OMPD_parallel_for_simd:
15636
109
      if (OpenMPVersion <= 45)
15637
71
        break;
15638
38
      if (NameModifier == OMPD_unknown || 
NameModifier == OMPD_simd16
)
15639
30
        CaptureRegion = OMPD_parallel;
15640
38
      break;
15641
57
    case OMPD_taskloop_simd:
15642
113
    case OMPD_master_taskloop_simd:
15643
162
    case OMPD_masked_taskloop_simd:
15644
162
      if (OpenMPVersion <= 45)
15645
10
        break;
15646
152
      if (NameModifier == OMPD_unknown || 
NameModifier == OMPD_simd96
)
15647
80
        CaptureRegion = OMPD_taskloop;
15648
152
      break;
15649
243
    case OMPD_distribute_parallel_for_simd:
15650
243
      if (OpenMPVersion <= 45)
15651
139
        break;
15652
104
      if (NameModifier == OMPD_unknown || 
NameModifier == OMPD_simd40
)
15653
72
        CaptureRegion = OMPD_parallel;
15654
104
      break;
15655
686
    case OMPD_target_simd:
15656
686
      if (OpenMPVersion >= 50 &&
15657
686
          
(405
NameModifier == OMPD_unknown405
||
NameModifier == OMPD_simd258
))
15658
167
        CaptureRegion = OMPD_target;
15659
686
      break;
15660
78
    case OMPD_teams_distribute_simd:
15661
651
    case OMPD_target_teams_distribute_simd:
15662
651
      if (OpenMPVersion >= 50 &&
15663
651
          
(396
NameModifier == OMPD_unknown396
||
NameModifier == OMPD_simd256
))
15664
202
        CaptureRegion = OMPD_teams;
15665
651
      break;
15666
146
    case OMPD_cancel:
15667
410
    case OMPD_parallel:
15668
540
    case OMPD_parallel_master:
15669
668
    case OMPD_parallel_masked:
15670
793
    case OMPD_parallel_sections:
15671
936
    case OMPD_parallel_for:
15672
940
    case OMPD_parallel_loop:
15673
1.51k
    case OMPD_target:
15674
2.05k
    case OMPD_target_teams:
15675
2.58k
    case OMPD_target_teams_distribute:
15676
2.89k
    case OMPD_distribute_parallel_for:
15677
3.10k
    case OMPD_task:
15678
3.13k
    case OMPD_taskloop:
15679
3.15k
    case OMPD_master_taskloop:
15680
3.18k
    case OMPD_masked_taskloop:
15681
3.39k
    case OMPD_target_data:
15682
3.47k
    case OMPD_simd:
15683
3.53k
    case OMPD_for_simd:
15684
3.66k
    case OMPD_distribute_simd:
15685
      // Do not capture if-clause expressions.
15686
3.66k
      break;
15687
0
    case OMPD_threadprivate:
15688
0
    case OMPD_allocate:
15689
0
    case OMPD_taskyield:
15690
0
    case OMPD_error:
15691
0
    case OMPD_barrier:
15692
0
    case OMPD_taskwait:
15693
0
    case OMPD_cancellation_point:
15694
0
    case OMPD_flush:
15695
0
    case OMPD_depobj:
15696
0
    case OMPD_scan:
15697
0
    case OMPD_declare_reduction:
15698
0
    case OMPD_declare_mapper:
15699
0
    case OMPD_declare_simd:
15700
0
    case OMPD_declare_variant:
15701
0
    case OMPD_begin_declare_variant:
15702
0
    case OMPD_end_declare_variant:
15703
0
    case OMPD_declare_target:
15704
0
    case OMPD_end_declare_target:
15705
0
    case OMPD_loop:
15706
0
    case OMPD_teams_loop:
15707
0
    case OMPD_teams:
15708
0
    case OMPD_tile:
15709
0
    case OMPD_unroll:
15710
0
    case OMPD_for:
15711
0
    case OMPD_sections:
15712
0
    case OMPD_section:
15713
0
    case OMPD_single:
15714
0
    case OMPD_master:
15715
0
    case OMPD_masked:
15716
0
    case OMPD_critical:
15717
0
    case OMPD_taskgroup:
15718
0
    case OMPD_distribute:
15719
0
    case OMPD_ordered:
15720
0
    case OMPD_atomic:
15721
0
    case OMPD_teams_distribute:
15722
0
    case OMPD_requires:
15723
0
    case OMPD_metadirective:
15724
0
      llvm_unreachable("Unexpected OpenMP directive with if-clause");
15725
0
    case OMPD_unknown:
15726
0
    default:
15727
0
      llvm_unreachable("Unknown OpenMP directive");
15728
10.8k
    }
15729
10.8k
    break;
15730
10.8k
  case OMPC_num_threads:
15731
2.26k
    switch (DKind) {
15732
446
    case OMPD_target_parallel:
15733
596
    case OMPD_target_parallel_for:
15734
794
    case OMPD_target_parallel_for_simd:
15735
809
    case OMPD_target_parallel_loop:
15736
809
      CaptureRegion = OMPD_target;
15737
809
      break;
15738
64
    case OMPD_teams_distribute_parallel_for:
15739
182
    case OMPD_teams_distribute_parallel_for_simd:
15740
242
    case OMPD_target_teams_distribute_parallel_for:
15741
298
    case OMPD_target_teams_distribute_parallel_for_simd:
15742
298
      CaptureRegion = OMPD_teams;
15743
298
      break;
15744
260
    case OMPD_parallel:
15745
346
    case OMPD_parallel_master:
15746
432
    case OMPD_parallel_masked:
15747
514
    case OMPD_parallel_sections:
15748
622
    case OMPD_parallel_for:
15749
682
    case OMPD_parallel_for_simd:
15750
690
    case OMPD_parallel_loop:
15751
932
    case OMPD_distribute_parallel_for:
15752
1.16k
    case OMPD_distribute_parallel_for_simd:
15753
1.16k
    case OMPD_parallel_master_taskloop:
15754
1.16k
    case OMPD_parallel_masked_taskloop:
15755
1.16k
    case OMPD_parallel_master_taskloop_simd:
15756
1.16k
    case OMPD_parallel_masked_taskloop_simd:
15757
      // Do not capture num_threads-clause expressions.
15758
1.16k
      break;
15759
0
    case OMPD_target_data:
15760
0
    case OMPD_target_enter_data:
15761
0
    case OMPD_target_exit_data:
15762
0
    case OMPD_target_update:
15763
0
    case OMPD_target:
15764
0
    case OMPD_target_simd:
15765
0
    case OMPD_target_teams:
15766
0
    case OMPD_target_teams_distribute:
15767
0
    case OMPD_target_teams_distribute_simd:
15768
0
    case OMPD_cancel:
15769
0
    case OMPD_task:
15770
0
    case OMPD_taskloop:
15771
0
    case OMPD_taskloop_simd:
15772
0
    case OMPD_master_taskloop:
15773
0
    case OMPD_masked_taskloop:
15774
0
    case OMPD_master_taskloop_simd:
15775
0
    case OMPD_masked_taskloop_simd:
15776
0
    case OMPD_threadprivate:
15777
0
    case OMPD_allocate:
15778
0
    case OMPD_taskyield:
15779
0
    case OMPD_error:
15780
0
    case OMPD_barrier:
15781
0
    case OMPD_taskwait:
15782
0
    case OMPD_cancellation_point:
15783
0
    case OMPD_flush:
15784
0
    case OMPD_depobj:
15785
0
    case OMPD_scan:
15786
0
    case OMPD_declare_reduction:
15787
0
    case OMPD_declare_mapper:
15788
0
    case OMPD_declare_simd:
15789
0
    case OMPD_declare_variant:
15790
0
    case OMPD_begin_declare_variant:
15791
0
    case OMPD_end_declare_variant:
15792
0
    case OMPD_declare_target:
15793
0
    case OMPD_end_declare_target:
15794
0
    case OMPD_loop:
15795
0
    case OMPD_teams_loop:
15796
0
    case OMPD_target_teams_loop:
15797
0
    case OMPD_teams:
15798
0
    case OMPD_simd:
15799
0
    case OMPD_tile:
15800
0
    case OMPD_unroll:
15801
0
    case OMPD_for:
15802
0
    case OMPD_for_simd:
15803
0
    case OMPD_sections:
15804
0
    case OMPD_section:
15805
0
    case OMPD_single:
15806
0
    case OMPD_master:
15807
0
    case OMPD_masked:
15808
0
    case OMPD_critical:
15809
0
    case OMPD_taskgroup:
15810
0
    case OMPD_distribute:
15811
0
    case OMPD_ordered:
15812
0
    case OMPD_atomic:
15813
0
    case OMPD_distribute_simd:
15814
0
    case OMPD_teams_distribute:
15815
0
    case OMPD_teams_distribute_simd:
15816
0
    case OMPD_requires:
15817
0
    case OMPD_metadirective:
15818
0
      llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
15819
0
    case OMPD_unknown:
15820
0
    default:
15821
0
      llvm_unreachable("Unknown OpenMP directive");
15822
2.26k
    }
15823
2.26k
    break;
15824
2.26k
  case OMPC_num_teams:
15825
1.96k
    switch (DKind) {
15826
644
    case OMPD_target_teams:
15827
762
    case OMPD_target_teams_distribute:
15828
920
    case OMPD_target_teams_distribute_simd:
15829
1.05k
    case OMPD_target_teams_distribute_parallel_for:
15830
1.20k
    case OMPD_target_teams_distribute_parallel_for_simd:
15831
1.24k
    case OMPD_target_teams_loop:
15832
1.24k
      CaptureRegion = OMPD_target;
15833
1.24k
      break;
15834
106
    case OMPD_teams_distribute_parallel_for:
15835
266
    case OMPD_teams_distribute_parallel_for_simd:
15836
454
    case OMPD_teams:
15837
544
    case OMPD_teams_distribute:
15838
682
    case OMPD_teams_distribute_simd:
15839
715
    case OMPD_teams_loop:
15840
      // Do not capture num_teams-clause expressions.
15841
715
      break;
15842
0
    case OMPD_distribute_parallel_for:
15843
0
    case OMPD_distribute_parallel_for_simd:
15844
0
    case OMPD_task:
15845
0
    case OMPD_taskloop:
15846
0
    case OMPD_taskloop_simd:
15847
0
    case OMPD_master_taskloop:
15848
0
    case OMPD_masked_taskloop:
15849
0
    case OMPD_master_taskloop_simd:
15850
0
    case OMPD_masked_taskloop_simd:
15851
0
    case OMPD_parallel_master_taskloop:
15852
0
    case OMPD_parallel_masked_taskloop:
15853
0
    case OMPD_parallel_master_taskloop_simd:
15854
0
    case OMPD_parallel_masked_taskloop_simd:
15855
0
    case OMPD_target_data:
15856
0
    case OMPD_target_enter_data:
15857
0
    case OMPD_target_exit_data:
15858
0
    case OMPD_target_update:
15859
0
    case OMPD_cancel:
15860
0
    case OMPD_parallel:
15861
0
    case OMPD_parallel_master:
15862
0
    case OMPD_parallel_masked:
15863
0
    case OMPD_parallel_sections:
15864
0
    case OMPD_parallel_for:
15865
0
    case OMPD_parallel_for_simd:
15866
0
    case OMPD_parallel_loop:
15867
0
    case OMPD_target:
15868
0
    case OMPD_target_simd:
15869
0
    case OMPD_target_parallel:
15870
0
    case OMPD_target_parallel_for:
15871
0
    case OMPD_target_parallel_for_simd:
15872
0
    case OMPD_target_parallel_loop:
15873
0
    case OMPD_threadprivate:
15874
0
    case OMPD_allocate:
15875
0
    case OMPD_taskyield:
15876
0
    case OMPD_error:
15877
0
    case OMPD_barrier:
15878
0
    case OMPD_taskwait:
15879
0
    case OMPD_cancellation_point:
15880
0
    case OMPD_flush:
15881
0
    case OMPD_depobj:
15882
0
    case OMPD_scan:
15883
0
    case OMPD_declare_reduction:
15884
0
    case OMPD_declare_mapper:
15885
0
    case OMPD_declare_simd:
15886
0
    case OMPD_declare_variant:
15887
0
    case OMPD_begin_declare_variant:
15888
0
    case OMPD_end_declare_variant:
15889
0
    case OMPD_declare_target:
15890
0
    case OMPD_end_declare_target:
15891
0
    case OMPD_loop:
15892
0
    case OMPD_simd:
15893
0
    case OMPD_tile:
15894
0
    case OMPD_unroll:
15895
0
    case OMPD_for:
15896
0
    case OMPD_for_simd:
15897
0
    case OMPD_sections:
15898
0
    case OMPD_section:
15899
0
    case OMPD_single:
15900
0
    case OMPD_master:
15901
0
    case OMPD_masked:
15902
0
    case OMPD_critical:
15903
0
    case OMPD_taskgroup:
15904
0
    case OMPD_distribute:
15905
0
    case OMPD_ordered:
15906
0
    case OMPD_atomic:
15907
0
    case OMPD_distribute_simd:
15908
0
    case OMPD_requires:
15909
0
    case OMPD_metadirective:
15910
0
      llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
15911
0
    case OMPD_unknown:
15912
0
    default:
15913
0
      llvm_unreachable("Unknown OpenMP directive");
15914
1.96k
    }
15915
1.96k
    break;
15916
1.96k
  case OMPC_thread_limit:
15917
1.64k
    switch (DKind) {
15918
24
    case OMPD_target:
15919
461
    case OMPD_target_teams:
15920
517
    case OMPD_target_teams_distribute:
15921
675
    case OMPD_target_teams_distribute_simd:
15922
802
    case OMPD_target_teams_distribute_parallel_for:
15923
916
    case OMPD_target_teams_distribute_parallel_for_simd:
15924
952
    case OMPD_target_teams_loop:
15925
954
    case OMPD_target_simd:
15926
956
    case OMPD_target_parallel:
15927
958
    case OMPD_target_parallel_for:
15928
960
    case OMPD_target_parallel_for_simd:
15929
962
    case OMPD_target_parallel_loop:
15930
962
      CaptureRegion = OMPD_target;
15931
962
      break;
15932
106
    case OMPD_teams_distribute_parallel_for:
15933
228
    case OMPD_teams_distribute_parallel_for_simd:
15934
424
    case OMPD_teams:
15935
514
    case OMPD_teams_distribute:
15936
652
    case OMPD_teams_distribute_simd:
15937
679
    case OMPD_teams_loop:
15938
      // Do not capture thread_limit-clause expressions.
15939
679
      break;
15940
0
    case OMPD_distribute_parallel_for:
15941
0
    case OMPD_distribute_parallel_for_simd:
15942
0
    case OMPD_task:
15943
0
    case OMPD_taskloop:
15944
0
    case OMPD_taskloop_simd:
15945
0
    case OMPD_master_taskloop:
15946
0
    case OMPD_masked_taskloop:
15947
0
    case OMPD_master_taskloop_simd:
15948
0
    case OMPD_masked_taskloop_simd:
15949
0
    case OMPD_parallel_master_taskloop:
15950
0
    case OMPD_parallel_masked_taskloop:
15951
0
    case OMPD_parallel_master_taskloop_simd:
15952
0
    case OMPD_parallel_masked_taskloop_simd:
15953
0
    case OMPD_target_data:
15954
0
    case OMPD_target_enter_data:
15955
0
    case OMPD_target_exit_data:
15956
0
    case OMPD_target_update:
15957
0
    case OMPD_cancel:
15958
0
    case OMPD_parallel:
15959
0
    case OMPD_parallel_master:
15960
0
    case OMPD_parallel_masked:
15961
0
    case OMPD_parallel_sections:
15962
0
    case OMPD_parallel_for:
15963
0
    case OMPD_parallel_for_simd:
15964
0
    case OMPD_parallel_loop:
15965
0
    case OMPD_threadprivate:
15966
0
    case OMPD_allocate:
15967
0
    case OMPD_taskyield:
15968
0
    case OMPD_error:
15969
0
    case OMPD_barrier:
15970
0
    case OMPD_taskwait:
15971
0
    case OMPD_cancellation_point:
15972
0
    case OMPD_flush:
15973
0
    case OMPD_depobj:
15974
0
    case OMPD_scan:
15975
0
    case OMPD_declare_reduction:
15976
0
    case OMPD_declare_mapper:
15977
0
    case OMPD_declare_simd:
15978
0
    case OMPD_declare_variant:
15979
0
    case OMPD_begin_declare_variant:
15980
0
    case OMPD_end_declare_variant:
15981
0
    case OMPD_declare_target:
15982
0
    case OMPD_end_declare_target:
15983
0
    case OMPD_loop:
15984
0
    case OMPD_simd:
15985
0
    case OMPD_tile:
15986
0
    case OMPD_unroll:
15987
0
    case OMPD_for:
15988
0
    case OMPD_for_simd:
15989
0
    case OMPD_sections:
15990
0
    case OMPD_section:
15991
0
    case OMPD_single:
15992
0
    case OMPD_master:
15993
0
    case OMPD_masked:
15994
0
    case OMPD_critical:
15995
0
    case OMPD_taskgroup:
15996
0
    case OMPD_distribute:
15997
0
    case OMPD_ordered:
15998
0
    case OMPD_atomic:
15999
0
    case OMPD_distribute_simd:
16000
0
    case OMPD_requires:
16001
0
    case OMPD_metadirective:
16002
0
      llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
16003
0
    case OMPD_unknown:
16004
0
    default:
16005
0
      llvm_unreachable("Unknown OpenMP directive");
16006
1.64k
    }
16007
1.64k
    break;
16008
1.64k
  case OMPC_schedule:
16009
836
    switch (DKind) {
16010
68
    case OMPD_parallel_for:
16011
88
    case OMPD_parallel_for_simd:
16012
210
    case OMPD_distribute_parallel_for:
16013
320
    case OMPD_distribute_parallel_for_simd:
16014
398
    case OMPD_teams_distribute_parallel_for:
16015
458
    case OMPD_teams_distribute_parallel_for_simd:
16016
524
    case OMPD_target_parallel_for:
16017
598
    case OMPD_target_parallel_for_simd:
16018
688
    case OMPD_target_teams_distribute_parallel_for:
16019
766
    case OMPD_target_teams_distribute_parallel_for_simd:
16020
766
      CaptureRegion = OMPD_parallel;
16021
766
      break;
16022
52
    case OMPD_for:
16023
70
    case OMPD_for_simd:
16024
      // Do not capture schedule-clause expressions.
16025
70
      break;
16026
0
    case OMPD_task:
16027
0
    case OMPD_taskloop:
16028
0
    case OMPD_taskloop_simd:
16029
0
    case OMPD_master_taskloop:
16030
0
    case OMPD_masked_taskloop:
16031
0
    case OMPD_master_taskloop_simd:
16032
0
    case OMPD_masked_taskloop_simd:
16033
0
    case OMPD_parallel_master_taskloop:
16034
0
    case OMPD_parallel_masked_taskloop:
16035
0
    case OMPD_parallel_master_taskloop_simd:
16036
0
    case OMPD_parallel_masked_taskloop_simd:
16037
0
    case OMPD_target_data:
16038
0
    case OMPD_target_enter_data:
16039
0
    case OMPD_target_exit_data:
16040
0
    case OMPD_target_update:
16041
0
    case OMPD_teams:
16042
0
    case OMPD_teams_distribute:
16043
0
    case OMPD_teams_distribute_simd:
16044
0
    case OMPD_target_teams_distribute:
16045
0
    case OMPD_target_teams_distribute_simd:
16046
0
    case OMPD_target:
16047
0
    case OMPD_target_simd:
16048
0
    case OMPD_target_parallel:
16049
0
    case OMPD_cancel:
16050
0
    case OMPD_parallel:
16051
0
    case OMPD_parallel_master:
16052
0
    case OMPD_parallel_masked:
16053
0
    case OMPD_parallel_sections:
16054
0
    case OMPD_threadprivate:
16055
0
    case OMPD_allocate:
16056
0
    case OMPD_taskyield:
16057
0
    case OMPD_error:
16058
0
    case OMPD_barrier:
16059
0
    case OMPD_taskwait:
16060
0
    case OMPD_cancellation_point:
16061
0
    case OMPD_flush:
16062
0
    case OMPD_depobj:
16063
0
    case OMPD_scan:
16064
0
    case OMPD_declare_reduction:
16065
0
    case OMPD_declare_mapper:
16066
0
    case OMPD_declare_simd:
16067
0
    case OMPD_declare_variant:
16068
0
    case OMPD_begin_declare_variant:
16069
0
    case OMPD_end_declare_variant:
16070
0
    case OMPD_declare_target:
16071
0
    case OMPD_end_declare_target:
16072
0
    case OMPD_loop:
16073
0
    case OMPD_teams_loop:
16074
0
    case OMPD_target_teams_loop:
16075
0
    case OMPD_parallel_loop:
16076
0
    case OMPD_target_parallel_loop:
16077
0
    case OMPD_simd:
16078
0
    case OMPD_tile:
16079
0
    case OMPD_unroll:
16080
0
    case OMPD_sections:
16081
0
    case OMPD_section:
16082
0
    case OMPD_single:
16083
0
    case OMPD_master:
16084
0
    case OMPD_masked:
16085
0
    case OMPD_critical:
16086
0
    case OMPD_taskgroup:
16087
0
    case OMPD_distribute:
16088
0
    case OMPD_ordered:
16089
0
    case OMPD_atomic:
16090
0
    case OMPD_distribute_simd:
16091
0
    case OMPD_target_teams:
16092
0
    case OMPD_requires:
16093
0
    case OMPD_metadirective:
16094
0
      llvm_unreachable("Unexpected OpenMP directive with schedule clause");
16095
0
    case OMPD_unknown:
16096
0
    default:
16097
0
      llvm_unreachable("Unknown OpenMP directive");
16098
836
    }
16099
836
    break;
16100
836
  case OMPC_dist_schedule:
16101
832
    switch (DKind) {
16102
52
    case OMPD_teams_distribute_parallel_for:
16103
104
    case OMPD_teams_distribute_parallel_for_simd:
16104
128
    case OMPD_teams_distribute:
16105
152
    case OMPD_teams_distribute_simd:
16106
204
    case OMPD_target_teams_distribute_parallel_for:
16107
256
    case OMPD_target_teams_distribute_parallel_for_simd:
16108
320
    case OMPD_target_teams_distribute:
16109
344
    case OMPD_target_teams_distribute_simd:
16110
344
      CaptureRegion = OMPD_teams;
16111
344
      break;
16112
128
    case OMPD_distribute_parallel_for:
16113
232
    case OMPD_distribute_parallel_for_simd:
16114
328
    case OMPD_distribute:
16115
488
    case OMPD_distribute_simd:
16116
      // Do not capture dist_schedule-clause expressions.
16117
488
      break;
16118
0
    case OMPD_parallel_for:
16119
0
    case OMPD_parallel_for_simd:
16120
0
    case OMPD_target_parallel_for_simd:
16121
0
    case OMPD_target_parallel_for:
16122
0
    case OMPD_task:
16123
0
    case OMPD_taskloop:
16124
0
    case OMPD_taskloop_simd:
16125
0
    case OMPD_master_taskloop:
16126
0
    case OMPD_masked_taskloop:
16127
0
    case OMPD_master_taskloop_simd:
16128
0
    case OMPD_masked_taskloop_simd:
16129
0
    case OMPD_parallel_master_taskloop:
16130
0
    case OMPD_parallel_masked_taskloop:
16131
0
    case OMPD_parallel_master_taskloop_simd:
16132
0
    case OMPD_parallel_masked_taskloop_simd:
16133
0
    case OMPD_target_data:
16134
0
    case OMPD_target_enter_data:
16135
0
    case OMPD_target_exit_data:
16136
0
    case OMPD_target_update:
16137
0
    case OMPD_teams:
16138
0
    case OMPD_target:
16139
0
    case OMPD_target_simd:
16140
0
    case OMPD_target_parallel:
16141
0
    case OMPD_cancel:
16142
0
    case OMPD_parallel:
16143
0
    case OMPD_parallel_master:
16144
0
    case OMPD_parallel_masked:
16145
0
    case OMPD_parallel_sections:
16146
0
    case OMPD_threadprivate:
16147
0
    case OMPD_allocate:
16148
0
    case OMPD_taskyield:
16149
0
    case OMPD_error:
16150
0
    case OMPD_barrier:
16151
0
    case OMPD_taskwait:
16152
0
    case OMPD_cancellation_point:
16153
0
    case OMPD_flush:
16154
0
    case OMPD_depobj:
16155
0
    case OMPD_scan:
16156
0
    case OMPD_declare_reduction:
16157
0
    case OMPD_declare_mapper:
16158
0
    case OMPD_declare_simd:
16159
0
    case OMPD_declare_variant:
16160
0
    case OMPD_begin_declare_variant:
16161
0
    case OMPD_end_declare_variant:
16162
0
    case OMPD_declare_target:
16163
0
    case OMPD_end_declare_target:
16164
0
    case OMPD_loop:
16165
0
    case OMPD_teams_loop:
16166
0
    case OMPD_target_teams_loop:
16167
0
    case OMPD_parallel_loop:
16168
0
    case OMPD_target_parallel_loop:
16169
0
    case OMPD_simd:
16170
0
    case OMPD_tile:
16171
0
    case OMPD_unroll:
16172
0
    case OMPD_for:
16173
0
    case OMPD_for_simd:
16174
0
    case OMPD_sections:
16175
0
    case OMPD_section:
16176
0
    case OMPD_single:
16177
0
    case OMPD_master:
16178
0
    case OMPD_masked:
16179
0
    case OMPD_critical:
16180
0
    case OMPD_taskgroup:
16181
0
    case OMPD_ordered:
16182
0
    case OMPD_atomic:
16183
0
    case OMPD_target_teams:
16184
0
    case OMPD_requires:
16185
0
    case OMPD_metadirective:
16186
0
      llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
16187
0
    case OMPD_unknown:
16188
0
    default:
16189
0
      llvm_unreachable("Unknown OpenMP directive");
16190
832
    }
16191
832
    break;
16192
832
  case OMPC_ompx_dyn_cgroup_mem:
16193
412
    switch (DKind) {
16194
132
    case OMPD_target:
16195
132
    case OMPD_target_simd:
16196
372
    case OMPD_target_teams:
16197
372
    case OMPD_target_parallel:
16198
372
    case OMPD_target_teams_distribute:
16199
372
    case OMPD_target_teams_distribute_simd:
16200
372
    case OMPD_target_parallel_for:
16201
372
    case OMPD_target_parallel_for_simd:
16202
372
    case OMPD_target_parallel_loop:
16203
372
    case OMPD_target_teams_distribute_parallel_for:
16204
412
    case OMPD_target_teams_distribute_parallel_for_simd:
16205
412
    case OMPD_target_teams_loop:
16206
412
      CaptureRegion = OMPD_target;
16207
412
      break;
16208
0
    default:
16209
0
      llvm_unreachable("Unknown OpenMP directive");
16210
412
    }
16211
412
    break;
16212
1.37k
  case OMPC_device:
16213
1.37k
    switch (DKind) {
16214
185
    case OMPD_target_update:
16215
295
    case OMPD_target_enter_data:
16216
385
    case OMPD_target_exit_data:
16217
636
    case OMPD_target:
16218
694
    case OMPD_target_simd:
16219
752
    case OMPD_target_teams:
16220
810
    case OMPD_target_parallel:
16221
868
    case OMPD_target_teams_distribute:
16222
934
    case OMPD_target_teams_distribute_simd:
16223
992
    case OMPD_target_parallel_for:
16224
1.05k
    case OMPD_target_parallel_for_simd:
16225
1.09k
    case OMPD_target_parallel_loop:
16226
1.15k
    case OMPD_target_teams_distribute_parallel_for:
16227
1.21k
    case OMPD_target_teams_distribute_parallel_for_simd:
16228
1.26k
    case OMPD_target_teams_loop:
16229
1.28k
    case OMPD_dispatch:
16230
1.28k
      CaptureRegion = OMPD_task;
16231
1.28k
      break;
16232
72
    case OMPD_target_data:
16233
91
    case OMPD_interop:
16234
      // Do not capture device-clause expressions.
16235
91
      break;
16236
0
    case OMPD_teams_distribute_parallel_for:
16237
0
    case OMPD_teams_distribute_parallel_for_simd:
16238
0
    case OMPD_teams:
16239
0
    case OMPD_teams_distribute:
16240
0
    case OMPD_teams_distribute_simd:
16241
0
    case OMPD_distribute_parallel_for:
16242
0
    case OMPD_distribute_parallel_for_simd:
16243
0
    case OMPD_task:
16244
0
    case OMPD_taskloop:
16245
0
    case OMPD_taskloop_simd:
16246
0
    case OMPD_master_taskloop:
16247
0
    case OMPD_masked_taskloop:
16248
0
    case OMPD_master_taskloop_simd:
16249
0
    case OMPD_masked_taskloop_simd:
16250
0
    case OMPD_parallel_master_taskloop:
16251
0
    case OMPD_parallel_masked_taskloop:
16252
0
    case OMPD_parallel_master_taskloop_simd:
16253
0
    case OMPD_parallel_masked_taskloop_simd:
16254
0
    case OMPD_cancel:
16255
0
    case OMPD_parallel:
16256
0
    case OMPD_parallel_master:
16257
0
    case OMPD_parallel_masked:
16258
0
    case OMPD_parallel_sections:
16259
0
    case OMPD_parallel_for:
16260
0
    case OMPD_parallel_for_simd:
16261
0
    case OMPD_threadprivate:
16262
0
    case OMPD_allocate:
16263
0
    case OMPD_taskyield:
16264
0
    case OMPD_error:
16265
0
    case OMPD_barrier:
16266
0
    case OMPD_taskwait:
16267
0
    case OMPD_cancellation_point:
16268
0
    case OMPD_flush:
16269
0
    case OMPD_depobj:
16270
0
    case OMPD_scan:
16271
0
    case OMPD_declare_reduction:
16272
0
    case OMPD_declare_mapper:
16273
0
    case OMPD_declare_simd:
16274
0
    case OMPD_declare_variant:
16275
0
    case OMPD_begin_declare_variant:
16276
0
    case OMPD_end_declare_variant:
16277
0
    case OMPD_declare_target:
16278
0
    case OMPD_end_declare_target:
16279
0
    case OMPD_loop:
16280
0
    case OMPD_teams_loop:
16281
0
    case OMPD_parallel_loop:
16282
0
    case OMPD_simd:
16283
0
    case OMPD_tile:
16284
0
    case OMPD_unroll:
16285
0
    case OMPD_for:
16286
0
    case OMPD_for_simd:
16287
0
    case OMPD_sections:
16288
0
    case OMPD_section:
16289
0
    case OMPD_single:
16290
0
    case OMPD_master:
16291
0
    case OMPD_masked:
16292
0
    case OMPD_critical:
16293
0
    case OMPD_taskgroup:
16294
0
    case OMPD_distribute:
16295
0
    case OMPD_ordered:
16296
0
    case OMPD_atomic:
16297
0
    case OMPD_distribute_simd:
16298
0
    case OMPD_requires:
16299
0
    case OMPD_metadirective:
16300
0
      llvm_unreachable("Unexpected OpenMP directive with device-clause");
16301
0
    case OMPD_unknown:
16302
0
    default:
16303
0
      llvm_unreachable("Unknown OpenMP directive");
16304
1.37k
    }
16305
1.37k
    break;
16306
1.37k
  case OMPC_grainsize:
16307
1.45k
  case OMPC_num_tasks:
16308
2.05k
  case OMPC_final:
16309
2.81k
  case OMPC_priority:
16310
2.81k
    switch (DKind) {
16311
165
    case OMPD_task:
16312
444
    case OMPD_taskloop:
16313
750
    case OMPD_taskloop_simd:
16314
992
    case OMPD_master_taskloop:
16315
1.21k
    case OMPD_masked_taskloop:
16316
1.53k
    case OMPD_master_taskloop_simd:
16317
1.82k
    case OMPD_masked_taskloop_simd:
16318
1.82k
      break;
16319
196
    case OMPD_parallel_masked_taskloop:
16320
422
    case OMPD_parallel_masked_taskloop_simd:
16321
668
    case OMPD_parallel_master_taskloop:
16322
994
    case OMPD_parallel_master_taskloop_simd:
16323
994
      CaptureRegion = OMPD_parallel;
16324
994
      break;
16325
0
    case OMPD_target_update:
16326
0
    case OMPD_target_enter_data:
16327
0
    case OMPD_target_exit_data:
16328
0
    case OMPD_target:
16329
0
    case OMPD_target_simd:
16330
0
    case OMPD_target_teams:
16331
0
    case OMPD_target_parallel:
16332
0
    case OMPD_target_teams_distribute:
16333
0
    case OMPD_target_teams_distribute_simd:
16334
0
    case OMPD_target_parallel_for:
16335
0
    case OMPD_target_parallel_for_simd:
16336
0
    case OMPD_target_teams_distribute_parallel_for:
16337
0
    case OMPD_target_teams_distribute_parallel_for_simd:
16338
0
    case OMPD_target_data:
16339
0
    case OMPD_teams_distribute_parallel_for:
16340
0
    case OMPD_teams_distribute_parallel_for_simd:
16341
0
    case OMPD_teams:
16342
0
    case OMPD_teams_distribute:
16343
0
    case OMPD_teams_distribute_simd:
16344
0
    case OMPD_distribute_parallel_for:
16345
0
    case OMPD_distribute_parallel_for_simd:
16346
0
    case OMPD_cancel:
16347
0
    case OMPD_parallel:
16348
0
    case OMPD_parallel_master:
16349
0
    case OMPD_parallel_masked:
16350
0
    case OMPD_parallel_sections:
16351
0
    case OMPD_parallel_for:
16352
0
    case OMPD_parallel_for_simd:
16353
0
    case OMPD_threadprivate:
16354
0
    case OMPD_allocate:
16355
0
    case OMPD_taskyield:
16356
0
    case OMPD_error:
16357
0
    case OMPD_barrier:
16358
0
    case OMPD_taskwait:
16359
0
    case OMPD_cancellation_point:
16360
0
    case OMPD_flush:
16361
0
    case OMPD_depobj:
16362
0
    case OMPD_scan:
16363
0
    case OMPD_declare_reduction:
16364
0
    case OMPD_declare_mapper:
16365
0
    case OMPD_declare_simd:
16366
0
    case OMPD_declare_variant:
16367
0
    case OMPD_begin_declare_variant:
16368
0
    case OMPD_end_declare_variant:
16369
0
    case OMPD_declare_target:
16370
0
    case OMPD_end_declare_target:
16371
0
    case OMPD_loop:
16372
0
    case OMPD_teams_loop:
16373
0
    case OMPD_target_teams_loop:
16374
0
    case OMPD_parallel_loop:
16375
0
    case OMPD_target_parallel_loop:
16376
0
    case OMPD_simd:
16377
0
    case OMPD_tile:
16378
0
    case OMPD_unroll:
16379
0
    case OMPD_for:
16380
0
    case OMPD_for_simd:
16381
0
    case OMPD_sections:
16382
0
    case OMPD_section:
16383
0
    case OMPD_single:
16384
0
    case OMPD_master:
16385
0
    case OMPD_masked:
16386
0
    case OMPD_critical:
16387
0
    case OMPD_taskgroup:
16388
0
    case OMPD_distribute:
16389
0
    case OMPD_ordered:
16390
0
    case OMPD_atomic:
16391
0
    case OMPD_distribute_simd:
16392
0
    case OMPD_requires:
16393
0
    case OMPD_metadirective:
16394
0
      llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
16395
0
    case OMPD_unknown:
16396
0
    default:
16397
0
      llvm_unreachable("Unknown OpenMP directive");
16398
2.81k
    }
16399
2.81k
    break;
16400
2.81k
  case OMPC_novariants:
16401
28
  case OMPC_nocontext:
16402
28
    switch (DKind) {
16403
28
    case OMPD_dispatch:
16404
28
      CaptureRegion = OMPD_task;
16405
28
      break;
16406
0
    default:
16407
0
      llvm_unreachable("Unexpected OpenMP directive");
16408
28
    }
16409
28
    break;
16410
313
  case OMPC_filter:
16411
    // Do not capture filter-clause expressions.
16412
313
    break;
16413
0
  case OMPC_when:
16414
0
    if (DKind == OMPD_metadirective) {
16415
0
      CaptureRegion = OMPD_metadirective;
16416
0
    } else if (DKind == OMPD_unknown) {
16417
0
      llvm_unreachable("Unknown OpenMP directive");
16418
0
    } else {
16419
0
      llvm_unreachable("Unexpected OpenMP directive with when clause");
16420
0
    }
16421
0
    break;
16422
0
  case OMPC_firstprivate:
16423
0
  case OMPC_lastprivate:
16424
0
  case OMPC_reduction:
16425
0
  case OMPC_task_reduction:
16426
0
  case OMPC_in_reduction:
16427
0
  case OMPC_linear:
16428
0
  case OMPC_default:
16429
0
  case OMPC_proc_bind:
16430
0
  case OMPC_safelen:
16431
0
  case OMPC_simdlen:
16432
0
  case OMPC_sizes:
16433
0
  case OMPC_allocator:
16434
0
  case OMPC_collapse:
16435
0
  case OMPC_private:
16436
0
  case OMPC_shared:
16437
0
  case OMPC_aligned:
16438
0
  case OMPC_copyin:
16439
0
  case OMPC_copyprivate:
16440
0
  case OMPC_ordered:
16441
0
  case OMPC_nowait:
16442
0
  case OMPC_untied:
16443
0
  case OMPC_mergeable:
16444
0
  case OMPC_threadprivate:
16445
0
  case OMPC_allocate:
16446
0
  case OMPC_flush:
16447
0
  case OMPC_depobj:
16448
0
  case OMPC_read:
16449
0
  case OMPC_write:
16450
0
  case OMPC_update:
16451
0
  case OMPC_capture:
16452
0
  case OMPC_compare:
16453
0
  case OMPC_seq_cst:
16454
0
  case OMPC_acq_rel:
16455
0
  case OMPC_acquire:
16456
0
  case OMPC_release:
16457
0
  case OMPC_relaxed:
16458
0
  case OMPC_depend:
16459
0
  case OMPC_threads:
16460
0
  case OMPC_simd:
16461
0
  case OMPC_map:
16462
0
  case OMPC_nogroup:
16463
0
  case OMPC_hint:
16464
0
  case OMPC_defaultmap:
16465
0
  case OMPC_unknown:
16466
0
  case OMPC_uniform:
16467
0
  case OMPC_to:
16468
0
  case OMPC_from:
16469
0
  case OMPC_use_device_ptr:
16470
0
  case OMPC_use_device_addr:
16471
0
  case OMPC_is_device_ptr:
16472
0
  case OMPC_unified_address:
16473
0
  case OMPC_unified_shared_memory:
16474
0
  case OMPC_reverse_offload:
16475
0
  case OMPC_dynamic_allocators:
16476
0
  case OMPC_atomic_default_mem_order:
16477
0
  case OMPC_device_type:
16478
0
  case OMPC_match:
16479
0
  case OMPC_nontemporal:
16480
0
  case OMPC_order:
16481
0
  case OMPC_at:
16482
0
  case OMPC_severity:
16483
0
  case OMPC_message:
16484
0
  case OMPC_destroy:
16485
0
  case OMPC_detach:
16486
0
  case OMPC_inclusive:
16487
0
  case OMPC_exclusive:
16488
0
  case OMPC_uses_allocators:
16489
0
  case OMPC_affinity:
16490
0
  case OMPC_bind:
16491
0
  default:
16492
0
    llvm_unreachable("Unexpected OpenMP clause.");
16493
23.3k
  }
16494
23.3k
  return CaptureRegion;
16495
23.3k
}
16496
16497
OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
16498
                                     Expr *Condition, SourceLocation StartLoc,
16499
                                     SourceLocation LParenLoc,
16500
                                     SourceLocation NameModifierLoc,
16501
                                     SourceLocation ColonLoc,
16502
13.5k
                                     SourceLocation EndLoc) {
16503
13.5k
  Expr *ValExpr = Condition;
16504
13.5k
  Stmt *HelperValStmt = nullptr;
16505
13.5k
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16506
13.5k
  if (!Condition->isValueDependent() && 
!Condition->isTypeDependent()10.8k
&&
16507
13.5k
      
!Condition->isInstantiationDependent()10.8k
&&
16508
13.5k
      
!Condition->containsUnexpandedParameterPack()10.8k
) {
16509
10.8k
    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16510
10.8k
    if (Val.isInvalid())
16511
0
      return nullptr;
16512
16513
10.8k
    ValExpr = Val.get();
16514
16515
10.8k
    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16516
10.8k
    CaptureRegion = getOpenMPCaptureRegionForClause(
16517
10.8k
        DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
16518
10.8k
    if (CaptureRegion != OMPD_unknown && 
!CurContext->isDependentContext()4.04k
) {
16519
3.72k
      ValExpr = MakeFullExpr(ValExpr).get();
16520
3.72k
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16521
3.72k
      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16522
3.72k
      HelperValStmt = buildPreInits(Context, Captures);
16523
3.72k
    }
16524
10.8k
  }
16525
16526
13.5k
  return new (Context)
16527
13.5k
      OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16528
13.5k
                  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16529
13.5k
}
16530
16531
OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
16532
                                        SourceLocation StartLoc,
16533
                                        SourceLocation LParenLoc,
16534
811
                                        SourceLocation EndLoc) {
16535
811
  Expr *ValExpr = Condition;
16536
811
  Stmt *HelperValStmt = nullptr;
16537
811
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16538
811
  if (!Condition->isValueDependent() && 
!Condition->isTypeDependent()597
&&
16539
811
      
!Condition->isInstantiationDependent()597
&&
16540
811
      
!Condition->containsUnexpandedParameterPack()597
) {
16541
597
    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16542
597
    if (Val.isInvalid())
16543
0
      return nullptr;
16544
16545
597
    ValExpr = MakeFullExpr(Val.get()).get();
16546
16547
597
    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16548
597
    CaptureRegion =
16549
597
        getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
16550
597
    if (CaptureRegion != OMPD_unknown && 
!CurContext->isDependentContext()200
) {
16551
192
      ValExpr = MakeFullExpr(ValExpr).get();
16552
192
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16553
192
      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16554
192
      HelperValStmt = buildPreInits(Context, Captures);
16555
192
    }
16556
597
  }
16557
16558
811
  return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
16559
811
                                      StartLoc, LParenLoc, EndLoc);
16560
811
}
16561
16562
ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
16563
260k
                                                        Expr *Op) {
16564
260k
  if (!Op)
16565
0
    return ExprError();
16566
16567
260k
  class IntConvertDiagnoser : public ICEConvertDiagnoser {
16568
260k
  public:
16569
260k
    IntConvertDiagnoser()
16570
260k
        : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
16571
260k
    SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
16572
260k
                                         QualType T) override {
16573
928
      return S.Diag(Loc, diag::err_omp_not_integral) << T;
16574
928
    }
16575
260k
    SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
16576
260k
                                             QualType T) override {
16577
0
      return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
16578
0
    }
16579
260k
    SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
16580
260k
                                               QualType T,
16581
260k
                                               QualType ConvTy) override {
16582
0
      return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16583
0
    }
16584
260k
    SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
16585
260k
                                           QualType ConvTy) override {
16586
0
      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16587
0
             << ConvTy->isEnumeralType() << ConvTy;
16588
0
    }
16589
260k
    SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
16590
260k
                                            QualType T) override {
16591
0
      return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16592
0
    }
16593
260k
    SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
16594
260k
                                        QualType ConvTy) override {
16595
0
      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16596
0
             << ConvTy->isEnumeralType() << ConvTy;
16597
0
    }
16598
260k
    SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
16599
260k
                                             QualType) override {
16600
0
      llvm_unreachable("conversion functions are permitted");
16601
0
    }
16602
260k
  } ConvertDiagnoser;
16603
260k
  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
16604
260k
}
16605
16606
static bool
16607
isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
16608
                          bool StrictlyPositive, bool BuildCapture = false,
16609
                          OpenMPDirectiveKind DKind = OMPD_unknown,
16610
                          OpenMPDirectiveKind *CaptureRegion = nullptr,
16611
11.2k
                          Stmt **HelperValStmt = nullptr) {
16612
11.2k
  if (!ValExpr->isTypeDependent() && 
!ValExpr->isValueDependent()9.59k
&&
16613
11.2k
      
!ValExpr->isInstantiationDependent()9.11k
) {
16614
9.11k
    SourceLocation Loc = ValExpr->getExprLoc();
16615
9.11k
    ExprResult Value =
16616
9.11k
        SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
16617
9.11k
    if (Value.isInvalid())
16618
0
      return false;
16619
16620
9.11k
    ValExpr = Value.get();
16621
    // The expression must evaluate to a non-negative integer value.
16622
9.11k
    if (std::optional<llvm::APSInt> Result =
16623
9.11k
            ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
16624
3.00k
      if (Result->isSigned() &&
16625
3.00k
          
!(2.60k
(2.60k
!StrictlyPositive2.60k
&&
Result->isNonNegative()670
) ||
16626
2.60k
            
(2.01k
StrictlyPositive2.01k
&&
Result->isStrictlyPositive()1.93k
))) {
16627
473
        SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
16628
473
            << getOpenMPClauseName(CKind) << (StrictlyPositive ? 
1396
:
077
)
16629
473
            << ValExpr->getSourceRange();
16630
473
        return false;
16631
473
      }
16632
3.00k
    }
16633
8.64k
    if (!BuildCapture)
16634
6.42k
      return true;
16635
2.21k
    *CaptureRegion =
16636
2.21k
        getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
16637
2.21k
    if (*CaptureRegion != OMPD_unknown &&
16638
2.21k
        
!SemaRef.CurContext->isDependentContext()794
) {
16639
756
      ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16640
756
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16641
756
      ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16642
756
      *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
16643
756
    }
16644
2.21k
  }
16645
4.37k
  return true;
16646
11.2k
}
16647
16648
OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
16649
                                             SourceLocation StartLoc,
16650
                                             SourceLocation LParenLoc,
16651
2.35k
                                             SourceLocation EndLoc) {
16652
2.35k
  Expr *ValExpr = NumThreads;
16653
2.35k
  Stmt *HelperValStmt = nullptr;
16654
16655
  // OpenMP [2.5, Restrictions]
16656
  //  The num_threads expression must evaluate to a positive integer value.
16657
2.35k
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
16658
2.35k
                                 /*StrictlyPositive=*/true))
16659
84
    return nullptr;
16660
16661
2.26k
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16662
2.26k
  OpenMPDirectiveKind CaptureRegion =
16663
2.26k
      getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
16664
2.26k
  if (CaptureRegion != OMPD_unknown && 
!CurContext->isDependentContext()1.10k
) {
16665
794
    ValExpr = MakeFullExpr(ValExpr).get();
16666
794
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16667
794
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16668
794
    HelperValStmt = buildPreInits(Context, Captures);
16669
794
  }
16670
16671
2.26k
  return new (Context) OMPNumThreadsClause(
16672
2.26k
      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16673
2.35k
}
16674
16675
ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
16676
                                                       OpenMPClauseKind CKind,
16677
                                                       bool StrictlyPositive,
16678
22.6k
                                                       bool SuppressExprDiags) {
16679
22.6k
  if (!E)
16680
0
    return ExprError();
16681
22.6k
  if (E->isValueDependent() || 
E->isTypeDependent()19.3k
||
16682
22.6k
      
E->isInstantiationDependent()19.3k
||
E->containsUnexpandedParameterPack()19.3k
)
16683
3.29k
    return E;
16684
16685
19.3k
  llvm::APSInt Result;
16686
19.3k
  ExprResult ICE;
16687
19.3k
  if (SuppressExprDiags) {
16688
    // Use a custom diagnoser that suppresses 'note' diagnostics about the
16689
    // expression.
16690
12
    struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
16691
12
      SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
16692
12
      Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
16693
12
                                                 SourceLocation Loc) override {
16694
0
        llvm_unreachable("Diagnostic suppressed");
16695
0
      }
16696
12
    } Diagnoser;
16697
12
    ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
16698
19.3k
  } else {
16699
19.3k
    ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
16700
19.3k
  }
16701
19.3k
  if (ICE.isInvalid())
16702
4.00k
    return ExprError();
16703
16704
15.3k
  if ((StrictlyPositive && 
!Result.isStrictlyPositive()14.8k
) ||
16705
15.3k
      
(12.9k
!StrictlyPositive12.9k
&&
!Result.isNonNegative()433
)) {
16706
2.36k
    Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
16707
2.36k
        << getOpenMPClauseName(CKind) << (StrictlyPositive ? 
12.36k
:
04
)
16708
2.36k
        << E->getSourceRange();
16709
2.36k
    return ExprError();
16710
2.36k
  }
16711
12.9k
  if ((CKind == OMPC_aligned || 
CKind == OMPC_align11.8k
) &&
!Result.isPowerOf2()1.16k
) {
16712
72
    Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16713
72
        << E->getSourceRange();
16714
72
    return ExprError();
16715
72
  }
16716
12.8k
  if (CKind == OMPC_collapse && 
DSAStack5.37k
->getAssociatedLoops() == 15.37k
)
16717
5.35k
    DSAStack->setAssociatedLoops(Result.getExtValue());
16718
7.52k
  else if (CKind == OMPC_ordered)
16719
560
    DSAStack->setAssociatedLoops(Result.getExtValue());
16720
12.8k
  return ICE;
16721
12.9k
}
16722
16723
OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
16724
                                          SourceLocation LParenLoc,
16725
5.80k
                                          SourceLocation EndLoc) {
16726
  // OpenMP [2.8.1, simd construct, Description]
16727
  // The parameter of the safelen clause must be a constant
16728
  // positive integer expression.
16729
5.80k
  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
16730
5.80k
  if (Safelen.isInvalid())
16731
1.82k
    return nullptr;
16732
3.97k
  return new (Context)
16733
3.97k
      OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
16734
5.80k
}
16735
16736
OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
16737
                                          SourceLocation LParenLoc,
16738
3.73k
                                          SourceLocation EndLoc) {
16739
  // OpenMP [2.8.1, simd construct, Description]
16740
  // The parameter of the simdlen clause must be a constant
16741
  // positive integer expression.
16742
3.73k
  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
16743
3.73k
  if (Simdlen.isInvalid())
16744
1.03k
    return nullptr;
16745
2.70k
  return new (Context)
16746
2.70k
      OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
16747
3.73k
}
16748
16749
/// Tries to find omp_allocator_handle_t type.
16750
static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
16751
3.01k
                                    DSAStackTy *Stack) {
16752
3.01k
  if (!Stack->getOMPAllocatorHandleT().isNull())
16753
1.96k
    return true;
16754
16755
  // Set the allocator handle type.
16756
1.04k
  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t");
16757
1.04k
  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16758
1.04k
  if (!PT.getAsOpaquePtr() || 
PT.get().isNull()1.03k
) {
16759
8
    S.Diag(Loc, diag::err_omp_implied_type_not_found)
16760
8
        << "omp_allocator_handle_t";
16761
8
    return false;
16762
8
  }
16763
1.03k
  QualType AllocatorHandleEnumTy = PT.get();
16764
1.03k
  AllocatorHandleEnumTy.addConst();
16765
1.03k
  Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
16766
16767
  // Fill the predefined allocator map.
16768
1.03k
  bool ErrorFound = false;
16769
10.3k
  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 
++I9.32k
) {
16770
9.32k
    auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
16771
9.32k
    StringRef Allocator =
16772
9.32k
        OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16773
9.32k
    DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
16774
9.32k
    auto *VD = dyn_cast_or_null<ValueDecl>(
16775
9.32k
        S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
16776
9.32k
    if (!VD) {
16777
0
      ErrorFound = true;
16778
0
      break;
16779
0
    }
16780
9.32k
    QualType AllocatorType =
16781
9.32k
        VD->getType().getNonLValueExprType(S.getASTContext());
16782
9.32k
    ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
16783
9.32k
    if (!Res.isUsable()) {
16784
0
      ErrorFound = true;
16785
0
      break;
16786
0
    }
16787
9.32k
    Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy,
16788
9.32k
                                      Sema::AA_Initializing,
16789
9.32k
                                      /* AllowExplicit */ true);
16790
9.32k
    if (!Res.isUsable()) {
16791
0
      ErrorFound = true;
16792
0
      break;
16793
0
    }
16794
9.32k
    Stack->setAllocator(AllocatorKind, Res.get());
16795
9.32k
  }
16796
1.03k
  if (ErrorFound) {
16797
0
    S.Diag(Loc, diag::err_omp_implied_type_not_found)
16798
0
        << "omp_allocator_handle_t";
16799
0
    return false;
16800
0
  }
16801
16802
1.03k
  return true;
16803
1.03k
}
16804
16805
OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
16806
                                            SourceLocation LParenLoc,
16807
470
                                            SourceLocation EndLoc) {
16808
  // OpenMP [2.11.3, allocate Directive, Description]
16809
  // allocator is an expression of omp_allocator_handle_t type.
16810
470
  if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
16811
8
    return nullptr;
16812
16813
462
  ExprResult Allocator = DefaultLvalueConversion(A);
16814
462
  if (Allocator.isInvalid())
16815
0
    return nullptr;
16816
462
  Allocator = PerformImplicitConversion(Allocator.get(),
16817
462
                                        DSAStack->getOMPAllocatorHandleT(),
16818
462
                                        Sema::AA_Initializing,
16819
462
                                        /*AllowExplicit=*/true);
16820
462
  if (Allocator.isInvalid())
16821
2
    return nullptr;
16822
460
  return new (Context)
16823
460
      OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
16824
462
}
16825
16826
OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
16827
                                           SourceLocation StartLoc,
16828
                                           SourceLocation LParenLoc,
16829
9.66k
                                           SourceLocation EndLoc) {
16830
  // OpenMP [2.7.1, loop construct, Description]
16831
  // OpenMP [2.8.1, simd construct, Description]
16832
  // OpenMP [2.9.6, distribute construct, Description]
16833
  // The parameter of the collapse clause must be a constant
16834
  // positive integer expression.
16835
9.66k
  ExprResult NumForLoopsResult =
16836
9.66k
      VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
16837
9.66k
  if (NumForLoopsResult.isInvalid())
16838
2.97k
    return nullptr;
16839
6.69k
  return new (Context)
16840
6.69k
      OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
16841
9.66k
}
16842
16843
OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
16844
                                          SourceLocation EndLoc,
16845
                                          SourceLocation LParenLoc,
16846
1.72k
                                          Expr *NumForLoops) {
16847
  // OpenMP [2.7.1, loop construct, Description]
16848
  // OpenMP [2.8.1, simd construct, Description]
16849
  // OpenMP [2.9.6, distribute construct, Description]
16850
  // The parameter of the ordered clause must be a constant
16851
  // positive integer expression if any.
16852
1.72k
  if (NumForLoops && 
LParenLoc.isValid()1.05k
) {
16853
1.05k
    ExprResult NumForLoopsResult =
16854
1.05k
        VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
16855
1.05k
    if (NumForLoopsResult.isInvalid())
16856
312
      return nullptr;
16857
742
    NumForLoops = NumForLoopsResult.get();
16858
742
  } else {
16859
671
    NumForLoops = nullptr;
16860
671
  }
16861
1.41k
  auto *Clause = OMPOrderedClause::Create(
16862
1.41k
      Context, NumForLoops, NumForLoops ? 
DSAStack742
->getAssociatedLoops()742
:
0671
,
16863
1.41k
      StartLoc, LParenLoc, EndLoc);
16864
1.41k
  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
16865
1.41k
  return Clause;
16866
1.72k
}
16867
16868
OMPClause *Sema::ActOnOpenMPSimpleClause(
16869
    OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
16870
3.71k
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16871
3.71k
  OMPClause *Res = nullptr;
16872
3.71k
  switch (Kind) {
16873
2.16k
  case OMPC_default:
16874
2.16k
    Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
16875
2.16k
                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16876
2.16k
    break;
16877
1.11k
  case OMPC_proc_bind:
16878
1.11k
    Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
16879
1.11k
                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16880
1.11k
    break;
16881
53
  case OMPC_atomic_default_mem_order:
16882
53
    Res = ActOnOpenMPAtomicDefaultMemOrderClause(
16883
53
        static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
16884
53
        ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16885
53
    break;
16886
64
  case OMPC_update:
16887
64
    Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
16888
64
                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16889
64
    break;
16890
184
  case OMPC_bind:
16891
184
    Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
16892
184
                                ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16893
184
    break;
16894
72
  case OMPC_at:
16895
72
    Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
16896
72
                              ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16897
72
    break;
16898
70
  case OMPC_severity:
16899
70
    Res = ActOnOpenMPSeverityClause(
16900
70
        static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
16901
70
        LParenLoc, EndLoc);
16902
70
    break;
16903
0
  case OMPC_if:
16904
0
  case OMPC_final:
16905
0
  case OMPC_num_threads:
16906
0
  case OMPC_safelen:
16907
0
  case OMPC_simdlen:
16908
0
  case OMPC_sizes:
16909
0
  case OMPC_allocator:
16910
0
  case OMPC_collapse:
16911
0
  case OMPC_schedule:
16912
0
  case OMPC_private:
16913
0
  case OMPC_firstprivate:
16914
0
  case OMPC_lastprivate:
16915
0
  case OMPC_shared:
16916
0
  case OMPC_reduction:
16917
0
  case OMPC_task_reduction:
16918
0
  case OMPC_in_reduction:
16919
0
  case OMPC_linear:
16920
0
  case OMPC_aligned:
16921
0
  case OMPC_copyin:
16922
0
  case OMPC_copyprivate:
16923
0
  case OMPC_ordered:
16924
0
  case OMPC_nowait:
16925
0
  case OMPC_untied:
16926
0
  case OMPC_mergeable:
16927
0
  case OMPC_threadprivate:
16928
0
  case OMPC_allocate:
16929
0
  case OMPC_flush:
16930
0
  case OMPC_depobj:
16931
0
  case OMPC_read:
16932
0
  case OMPC_write:
16933
0
  case OMPC_capture:
16934
0
  case OMPC_compare:
16935
0
  case OMPC_seq_cst:
16936
0
  case OMPC_acq_rel:
16937
0
  case OMPC_acquire:
16938
0
  case OMPC_release:
16939
0
  case OMPC_relaxed:
16940
0
  case OMPC_depend:
16941
0
  case OMPC_device:
16942
0
  case OMPC_threads:
16943
0
  case OMPC_simd:
16944
0
  case OMPC_map:
16945
0
  case OMPC_num_teams:
16946
0
  case OMPC_thread_limit:
16947
0
  case OMPC_priority:
16948
0
  case OMPC_grainsize:
16949
0
  case OMPC_nogroup:
16950
0
  case OMPC_num_tasks:
16951
0
  case OMPC_hint:
16952
0
  case OMPC_dist_schedule:
16953
0
  case OMPC_defaultmap:
16954
0
  case OMPC_unknown:
16955
0
  case OMPC_uniform:
16956
0
  case OMPC_to:
16957
0
  case OMPC_from:
16958
0
  case OMPC_use_device_ptr:
16959
0
  case OMPC_use_device_addr:
16960
0
  case OMPC_is_device_ptr:
16961
0
  case OMPC_has_device_addr:
16962
0
  case OMPC_unified_address:
16963
0
  case OMPC_unified_shared_memory:
16964
0
  case OMPC_reverse_offload:
16965
0
  case OMPC_dynamic_allocators:
16966
0
  case OMPC_device_type:
16967
0
  case OMPC_match:
16968
0
  case OMPC_nontemporal:
16969
0
  case OMPC_destroy:
16970
0
  case OMPC_novariants:
16971
0
  case OMPC_nocontext:
16972
0
  case OMPC_detach:
16973
0
  case OMPC_inclusive:
16974
0
  case OMPC_exclusive:
16975
0
  case OMPC_uses_allocators:
16976
0
  case OMPC_affinity:
16977
0
  case OMPC_when:
16978
0
  case OMPC_message:
16979
0
  default:
16980
0
    llvm_unreachable("Clause is not allowed.");
16981
3.71k
  }
16982
3.71k
  return Res;
16983
3.71k
}
16984
16985
static std::string
16986
getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
16987
1.70k
                        ArrayRef<unsigned> Exclude = std::nullopt) {
16988
1.70k
  SmallString<256> Buffer;
16989
1.70k
  llvm::raw_svector_ostream Out(Buffer);
16990
1.70k
  unsigned Skipped = Exclude.size();
16991
11.4k
  for (unsigned I = First; I < Last; 
++I9.75k
) {
16992
9.75k
    if (llvm::is_contained(Exclude, I)) {
16993
3.14k
      --Skipped;
16994
3.14k
      continue;
16995
3.14k
    }
16996
6.61k
    Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
16997
6.61k
    if (I + Skipped + 2 == Last)
16998
1.30k
      Out << " or ";
16999
5.30k
    else if (I + Skipped + 1 != Last)
17000
3.60k
      Out << ", ";
17001
6.61k
  }
17002
1.70k
  return std::string(Out.str());
17003
1.70k
}
17004
17005
OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
17006
                                          SourceLocation KindKwLoc,
17007
                                          SourceLocation StartLoc,
17008
                                          SourceLocation LParenLoc,
17009
2.77k
                                          SourceLocation EndLoc) {
17010
2.77k
  if (Kind == OMP_DEFAULT_unknown) {
17011
274
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17012
274
        << getListOfPossibleValues(OMPC_default, /*First=*/0,
17013
274
                                   /*Last=*/unsigned(OMP_DEFAULT_unknown))
17014
274
        << getOpenMPClauseName(OMPC_default);
17015
274
    return nullptr;
17016
274
  }
17017
17018
2.50k
  switch (Kind) {
17019
1.38k
  case OMP_DEFAULT_none:
17020
1.38k
    DSAStack->setDefaultDSANone(KindKwLoc);
17021
1.38k
    break;
17022
898
  case OMP_DEFAULT_shared:
17023
898
    DSAStack->setDefaultDSAShared(KindKwLoc);
17024
898
    break;
17025
123
  case OMP_DEFAULT_firstprivate:
17026
123
    DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
17027
123
    break;
17028
96
  case OMP_DEFAULT_private:
17029
96
    DSAStack->setDefaultDSAPrivate(KindKwLoc);
17030
96
    break;
17031
0
  default:
17032
0
    llvm_unreachable("DSA unexpected in OpenMP default clause");
17033
2.50k
  }
17034
17035
2.50k
  return new (Context)
17036
2.50k
      OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17037
2.50k
}
17038
17039
OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
17040
                                           SourceLocation KindKwLoc,
17041
                                           SourceLocation StartLoc,
17042
                                           SourceLocation LParenLoc,
17043
1.47k
                                           SourceLocation EndLoc) {
17044
1.47k
  if (Kind == OMP_PROC_BIND_unknown) {
17045
258
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17046
258
        << getListOfPossibleValues(OMPC_proc_bind,
17047
258
                                   /*First=*/unsigned(OMP_PROC_BIND_master),
17048
                                   /*Last=*/
17049
258
                                   unsigned(LangOpts.OpenMP > 50
17050
258
                                                ? 
OMP_PROC_BIND_primary126
17051
258
                                                : 
OMP_PROC_BIND_spread132
) +
17052
258
                                       1)
17053
258
        << getOpenMPClauseName(OMPC_proc_bind);
17054
258
    return nullptr;
17055
258
  }
17056
1.21k
  if (Kind == OMP_PROC_BIND_primary && 
LangOpts.OpenMP < 5135
)
17057
4
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17058
4
        << getListOfPossibleValues(OMPC_proc_bind,
17059
4
                                   /*First=*/unsigned(OMP_PROC_BIND_master),
17060
                                   /*Last=*/
17061
4
                                   unsigned(OMP_PROC_BIND_spread) + 1)
17062
4
        << getOpenMPClauseName(OMPC_proc_bind);
17063
1.21k
  return new (Context)
17064
1.21k
      OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17065
1.47k
}
17066
17067
OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
17068
    OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
17069
53
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
17070
53
  if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
17071
7
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17072
7
        << getListOfPossibleValues(
17073
7
               OMPC_atomic_default_mem_order, /*First=*/0,
17074
7
               /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
17075
7
        << getOpenMPClauseName(OMPC_atomic_default_mem_order);
17076
7
    return nullptr;
17077
7
  }
17078
46
  return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
17079
46
                                                      LParenLoc, EndLoc);
17080
53
}
17081
17082
OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
17083
                                     SourceLocation KindKwLoc,
17084
                                     SourceLocation StartLoc,
17085
                                     SourceLocation LParenLoc,
17086
94
                                     SourceLocation EndLoc) {
17087
94
  if (Kind == OMPC_AT_unknown) {
17088
6
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17089
6
        << getListOfPossibleValues(OMPC_at, /*First=*/0,
17090
6
                                   /*Last=*/OMPC_AT_unknown)
17091
6
        << getOpenMPClauseName(OMPC_at);
17092
6
    return nullptr;
17093
6
  }
17094
88
  return new (Context)
17095
88
      OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17096
94
}
17097
17098
OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
17099
                                           SourceLocation KindKwLoc,
17100
                                           SourceLocation StartLoc,
17101
                                           SourceLocation LParenLoc,
17102
94
                                           SourceLocation EndLoc) {
17103
94
  if (Kind == OMPC_SEVERITY_unknown) {
17104
4
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17105
4
        << getListOfPossibleValues(OMPC_severity, /*First=*/0,
17106
4
                                   /*Last=*/OMPC_SEVERITY_unknown)
17107
4
        << getOpenMPClauseName(OMPC_severity);
17108
4
    return nullptr;
17109
4
  }
17110
90
  return new (Context)
17111
90
      OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17112
94
}
17113
17114
OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc,
17115
                                          SourceLocation LParenLoc,
17116
70
                                          SourceLocation EndLoc) {
17117
70
  assert(ME && "NULL expr in Message clause");
17118
70
  if (!isa<StringLiteral>(ME)) {
17119
2
    Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
17120
2
        << getOpenMPClauseName(OMPC_message);
17121
2
    return nullptr;
17122
2
  }
17123
68
  return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
17124
70
}
17125
17126
OMPClause *Sema::ActOnOpenMPOrderClause(
17127
    OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind,
17128
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
17129
1.03k
    SourceLocation KindLoc, SourceLocation EndLoc) {
17130
1.03k
  if (Kind != OMPC_ORDER_concurrent ||
17131
1.03k
      
(815
LangOpts.OpenMP < 51815
&&
MLoc.isValid()335
)) {
17132
    // Kind should be concurrent,
17133
    // Modifiers introduced in OpenMP 5.1
17134
337
    static_assert(OMPC_ORDER_unknown > 0,
17135
337
                  "OMPC_ORDER_unknown not greater than 0");
17136
17137
337
    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17138
337
        << getListOfPossibleValues(OMPC_order,
17139
337
                                   /*First=*/0,
17140
337
                                   /*Last=*/OMPC_ORDER_unknown)
17141
337
        << getOpenMPClauseName(OMPC_order);
17142
337
    return nullptr;
17143
337
  }
17144
699
  if (LangOpts.OpenMP >= 51) {
17145
480
    if (Modifier == OMPC_ORDER_MODIFIER_unknown && 
MLoc.isValid()224
) {
17146
0
      Diag(MLoc, diag::err_omp_unexpected_clause_value)
17147
0
          << getListOfPossibleValues(OMPC_order,
17148
0
                                     /*First=*/OMPC_ORDER_MODIFIER_unknown + 1,
17149
0
                                     /*Last=*/OMPC_ORDER_MODIFIER_last)
17150
0
          << getOpenMPClauseName(OMPC_order);
17151
480
    } else {
17152
480
      DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true);
17153
480
      if (DSAStack->getCurScope()) {
17154
        // mark the current scope with 'order' flag
17155
440
        unsigned existingFlags = DSAStack->getCurScope()->getFlags();
17156
440
        DSAStack->getCurScope()->setFlags(existingFlags |
17157
440
                                          Scope::OpenMPOrderClauseScope);
17158
440
      }
17159
480
    }
17160
480
  }
17161
699
  return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc,
17162
699
                                      EndLoc, Modifier, MLoc);
17163
1.03k
}
17164
17165
OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
17166
                                         SourceLocation KindKwLoc,
17167
                                         SourceLocation StartLoc,
17168
                                         SourceLocation LParenLoc,
17169
64
                                         SourceLocation EndLoc) {
17170
64
  if (Kind == OMPC_DEPEND_unknown || 
Kind == OMPC_DEPEND_source58
||
17171
64
      
Kind == OMPC_DEPEND_sink58
||
Kind == OMPC_DEPEND_depobj52
) {
17172
12
    SmallVector<unsigned> Except = {
17173
12
        OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
17174
12
        OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
17175
12
    if (LangOpts.OpenMP < 51)
17176
4
      Except.push_back(OMPC_DEPEND_inoutset);
17177
12
    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17178
12
        << getListOfPossibleValues(OMPC_depend, /*First=*/0,
17179
12
                                   /*Last=*/OMPC_DEPEND_unknown, Except)
17180
12
        << getOpenMPClauseName(OMPC_update);
17181
12
    return nullptr;
17182
12
  }
17183
52
  return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
17184
52
                                 EndLoc);
17185
64
}
17186
17187
OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
17188
                                        SourceLocation StartLoc,
17189
                                        SourceLocation LParenLoc,
17190
82
                                        SourceLocation EndLoc) {
17191
105
  for (Expr *SizeExpr : SizeExprs) {
17192
105
    ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
17193
105
        SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
17194
105
    if (!NumForLoopsResult.isUsable())
17195
2
      return nullptr;
17196
105
  }
17197
17198
80
  DSAStack->setAssociatedLoops(SizeExprs.size());
17199
80
  return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17200
80
                                SizeExprs);
17201
82
}
17202
17203
OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
17204
15
                                       SourceLocation EndLoc) {
17205
15
  return OMPFullClause::Create(Context, StartLoc, EndLoc);
17206
15
}
17207
17208
OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
17209
                                          SourceLocation StartLoc,
17210
                                          SourceLocation LParenLoc,
17211
73
                                          SourceLocation EndLoc) {
17212
73
  if (FactorExpr) {
17213
    // If an argument is specified, it must be a constant (or an unevaluated
17214
    // template expression).
17215
42
    ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
17216
42
        FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
17217
42
    if (FactorResult.isInvalid())
17218
4
      return nullptr;
17219
38
    FactorExpr = FactorResult.get();
17220
38
  }
17221
17222
69
  return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17223
69
                                  FactorExpr);
17224
73
}
17225
17226
OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
17227
                                        SourceLocation LParenLoc,
17228
83
                                        SourceLocation EndLoc) {
17229
83
  ExprResult AlignVal;
17230
83
  AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
17231
83
  if (AlignVal.isInvalid())
17232
6
    return nullptr;
17233
77
  return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
17234
77
                                EndLoc);
17235
83
}
17236
17237
OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
17238
    OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
17239
    SourceLocation StartLoc, SourceLocation LParenLoc,
17240
    ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
17241
21.1k
    SourceLocation EndLoc) {
17242
21.1k
  OMPClause *Res = nullptr;
17243
21.1k
  switch (Kind) {
17244
2.73k
  case OMPC_schedule:
17245
2.73k
    enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
17246
2.73k
    assert(Argument.size() == NumberOfElements &&
17247
2.73k
           ArgumentLoc.size() == NumberOfElements);
17248
2.73k
    Res = ActOnOpenMPScheduleClause(
17249
2.73k
        static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
17250
2.73k
        static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
17251
2.73k
        static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
17252
2.73k
        StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
17253
2.73k
        ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
17254
2.73k
    break;
17255
10.5k
  case OMPC_if:
17256
10.5k
    assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17257
10.5k
    Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
17258
10.5k
                              Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
17259
10.5k
                              DelimLoc, EndLoc);
17260
10.5k
    break;
17261
1.47k
  case OMPC_dist_schedule:
17262
1.47k
    Res = ActOnOpenMPDistScheduleClause(
17263
1.47k
        static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
17264
1.47k
        StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
17265
1.47k
    break;
17266
2.35k
  case OMPC_defaultmap:
17267
2.35k
    enum { Modifier, DefaultmapKind };
17268
2.35k
    Res = ActOnOpenMPDefaultmapClause(
17269
2.35k
        static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
17270
2.35k
        static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
17271
2.35k
        StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
17272
2.35k
        EndLoc);
17273
2.35k
    break;
17274
984
  case OMPC_order:
17275
984
    enum { OrderModifier, OrderKind };
17276
984
    Res = ActOnOpenMPOrderClause(
17277
984
        static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]),
17278
984
        static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc,
17279
984
        LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
17280
984
    break;
17281
1.25k
  case OMPC_device:
17282
1.25k
    assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17283
1.25k
    Res = ActOnOpenMPDeviceClause(
17284
1.25k
        static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
17285
1.25k
        StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17286
1.25k
    break;
17287
1.06k
  case OMPC_grainsize:
17288
1.06k
    assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17289
1.06k
           "Modifier for grainsize clause and its location are expected.");
17290
1.06k
    Res = ActOnOpenMPGrainsizeClause(
17291
1.06k
        static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr,
17292
1.06k
        StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17293
1.06k
    break;
17294
785
  case OMPC_num_tasks:
17295
785
    assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17296
785
           "Modifier for num_tasks clause and its location are expected.");
17297
785
    Res = ActOnOpenMPNumTasksClause(
17298
785
        static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
17299
785
        StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17300
785
    break;
17301
0
  case OMPC_final:
17302
0
  case OMPC_num_threads:
17303
0
  case OMPC_safelen:
17304
0
  case OMPC_simdlen:
17305
0
  case OMPC_sizes:
17306
0
  case OMPC_allocator:
17307
0
  case OMPC_collapse:
17308
0
  case OMPC_default:
17309
0
  case OMPC_proc_bind:
17310
0
  case OMPC_private:
17311
0
  case OMPC_firstprivate:
17312
0
  case OMPC_lastprivate:
17313
0
  case OMPC_shared:
17314
0
  case OMPC_reduction:
17315
0
  case OMPC_task_reduction:
17316
0
  case OMPC_in_reduction:
17317
0
  case OMPC_linear:
17318
0
  case OMPC_aligned:
17319
0
  case OMPC_copyin:
17320
0
  case OMPC_copyprivate:
17321
0
  case OMPC_ordered:
17322
0
  case OMPC_nowait:
17323
0
  case OMPC_untied:
17324
0
  case OMPC_mergeable:
17325
0
  case OMPC_threadprivate:
17326
0
  case OMPC_allocate:
17327
0
  case OMPC_flush:
17328
0
  case OMPC_depobj:
17329
0
  case OMPC_read:
17330
0
  case OMPC_write:
17331
0
  case OMPC_update:
17332
0
  case OMPC_capture:
17333
0
  case OMPC_compare:
17334
0
  case OMPC_seq_cst:
17335
0
  case OMPC_acq_rel:
17336
0
  case OMPC_acquire:
17337
0
  case OMPC_release:
17338
0
  case OMPC_relaxed:
17339
0
  case OMPC_depend:
17340
0
  case OMPC_threads:
17341
0
  case OMPC_simd:
17342
0
  case OMPC_map:
17343
0
  case OMPC_num_teams:
17344
0
  case OMPC_thread_limit:
17345
0
  case OMPC_priority:
17346
0
  case OMPC_nogroup:
17347
0
  case OMPC_hint:
17348
0
  case OMPC_unknown:
17349
0
  case OMPC_uniform:
17350
0
  case OMPC_to:
17351
0
  case OMPC_from:
17352
0
  case OMPC_use_device_ptr:
17353
0
  case OMPC_use_device_addr:
17354
0
  case OMPC_is_device_ptr:
17355
0
  case OMPC_has_device_addr:
17356
0
  case OMPC_unified_address:
17357
0
  case OMPC_unified_shared_memory:
17358
0
  case OMPC_reverse_offload:
17359
0
  case OMPC_dynamic_allocators:
17360
0
  case OMPC_atomic_default_mem_order:
17361
0
  case OMPC_device_type:
17362
0
  case OMPC_match:
17363
0
  case OMPC_nontemporal:
17364
0
  case OMPC_at:
17365
0
  case OMPC_severity:
17366
0
  case OMPC_message:
17367
0
  case OMPC_destroy:
17368
0
  case OMPC_novariants:
17369
0
  case OMPC_nocontext:
17370
0
  case OMPC_detach:
17371
0
  case OMPC_inclusive:
17372
0
  case OMPC_exclusive:
17373
0
  case OMPC_uses_allocators:
17374
0
  case OMPC_affinity:
17375
0
  case OMPC_when:
17376
0
  case OMPC_bind:
17377
0
  default:
17378
0
    llvm_unreachable("Clause is not allowed.");
17379
21.1k
  }
17380
21.1k
  return Res;
17381
21.1k
}
17382
17383
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
17384
                                   OpenMPScheduleClauseModifier M2,
17385
8.51k
                                   SourceLocation M1Loc, SourceLocation M2Loc) {
17386
8.51k
  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && 
M1Loc.isValid()7.95k
) {
17387
8
    SmallVector<unsigned, 2> Excluded;
17388
8
    if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
17389
8
      Excluded.push_back(M2);
17390
8
    if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17391
4
      Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17392
8
    if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17393
4
      Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17394
8
    S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17395
8
        << getListOfPossibleValues(OMPC_schedule,
17396
8
                                   /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
17397
8
                                   /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17398
8
                                   Excluded)
17399
8
        << getOpenMPClauseName(OMPC_schedule);
17400
8
    return true;
17401
8
  }
17402
8.50k
  return false;
17403
8.51k
}
17404
17405
OMPClause *Sema::ActOnOpenMPScheduleClause(
17406
    OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
17407
    OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
17408
    SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
17409
4.25k
    SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
17410
4.25k
  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
17411
4.25k
      checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
17412
8
    return nullptr;
17413
  // OpenMP, 2.7.1, Loop Construct, Restrictions
17414
  // Either the monotonic modifier or the nonmonotonic modifier can be specified
17415
  // but not both.
17416
4.24k
  if ((M1 == M2 && 
M1 != OMPC_SCHEDULE_MODIFIER_unknown3.73k
) ||
17417
4.24k
      
(4.24k
M1 == OMPC_SCHEDULE_MODIFIER_monotonic4.24k
&&
17418
4.24k
       
M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic223
) ||
17419
4.24k
      
(4.23k
M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic4.23k
&&
17420
4.23k
       
M2 == OMPC_SCHEDULE_MODIFIER_monotonic249
)) {
17421
16
    Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17422
16
        << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
17423
16
        << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
17424
16
    return nullptr;
17425
16
  }
17426
4.23k
  if (Kind == OMPC_SCHEDULE_unknown) {
17427
152
    std::string Values;
17428
152
    if (M1Loc.isInvalid() && 
M2Loc.isInvalid()144
) {
17429
144
      unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
17430
144
      Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17431
144
                                       /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17432
144
                                       Exclude);
17433
144
    } else {
17434
8
      Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17435
8
                                       /*Last=*/OMPC_SCHEDULE_unknown);
17436
8
    }
17437
152
    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17438
152
        << Values << getOpenMPClauseName(OMPC_schedule);
17439
152
    return nullptr;
17440
152
  }
17441
  // OpenMP, 2.7.1, Loop Construct, Restrictions
17442
  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
17443
  // schedule(guided).
17444
  // OpenMP 5.0 does not have this restriction.
17445
4.08k
  if (LangOpts.OpenMP < 50 &&
17446
4.08k
      
(976
M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic976
||
17447
976
       
M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic962
) &&
17448
4.08k
      
Kind != OMPC_SCHEDULE_dynamic20
&&
Kind != OMPC_SCHEDULE_guided10
) {
17449
8
    Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : 
M2Loc0
,
17450
8
         diag::err_omp_schedule_nonmonotonic_static);
17451
8
    return nullptr;
17452
8
  }
17453
4.07k
  Expr *ValExpr = ChunkSize;
17454
4.07k
  Stmt *HelperValStmt = nullptr;
17455
4.07k
  if (ChunkSize) {
17456
1.90k
    if (!ChunkSize->isValueDependent() && 
!ChunkSize->isTypeDependent()1.59k
&&
17457
1.90k
        
!ChunkSize->isInstantiationDependent()1.59k
&&
17458
1.90k
        
!ChunkSize->containsUnexpandedParameterPack()1.59k
) {
17459
1.59k
      SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
17460
1.59k
      ExprResult Val =
17461
1.59k
          PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
17462
1.59k
      if (Val.isInvalid())
17463
0
        return nullptr;
17464
17465
1.59k
      ValExpr = Val.get();
17466
17467
      // OpenMP [2.7.1, Restrictions]
17468
      //  chunk_size must be a loop invariant integer expression with a positive
17469
      //  value.
17470
1.59k
      if (std::optional<llvm::APSInt> Result =
17471
1.59k
              ValExpr->getIntegerConstantExpr(Context)) {
17472
759
        if (Result->isSigned() && 
!Result->isStrictlyPositive()699
) {
17473
120
          Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17474
120
              << "schedule" << 1 << ChunkSize->getSourceRange();
17475
120
          return nullptr;
17476
120
        }
17477
836
      } else if (getOpenMPCaptureRegionForClause(
17478
836
                     DSAStack->getCurrentDirective(), OMPC_schedule,
17479
836
                     LangOpts.OpenMP) != OMPD_unknown &&
17480
836
                 
!CurContext->isDependentContext()766
) {
17481
595
        ValExpr = MakeFullExpr(ValExpr).get();
17482
595
        llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17483
595
        ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17484
595
        HelperValStmt = buildPreInits(Context, Captures);
17485
595
      }
17486
1.59k
    }
17487
1.90k
  }
17488
17489
3.95k
  return new (Context)
17490
3.95k
      OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
17491
3.95k
                        ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17492
4.07k
}
17493
17494
OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
17495
                                   SourceLocation StartLoc,
17496
35.5k
                                   SourceLocation EndLoc) {
17497
35.5k
  OMPClause *Res = nullptr;
17498
35.5k
  switch (Kind) {
17499
497
  case OMPC_ordered:
17500
497
    Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
17501
497
    break;
17502
1.82k
  case OMPC_nowait:
17503
1.82k
    Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
17504
1.82k
    break;
17505
148
  case OMPC_untied:
17506
148
    Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
17507
148
    break;
17508
168
  case OMPC_mergeable:
17509
168
    Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
17510
168
    break;
17511
531
  case OMPC_read:
17512
531
    Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
17513
531
    break;
17514
524
  case OMPC_write:
17515
524
    Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
17516
524
    break;
17517
635
  case OMPC_update:
17518
635
    Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
17519
635
    break;
17520
9.40k
  case OMPC_capture:
17521
9.40k
    Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
17522
9.40k
    break;
17523
10.9k
  case OMPC_compare:
17524
10.9k
    Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
17525
10.9k
    break;
17526
2.07k
  case OMPC_seq_cst:
17527
2.07k
    Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
17528
2.07k
    break;
17529
1.89k
  case OMPC_acq_rel:
17530
1.89k
    Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
17531
1.89k
    break;
17532
1.91k
  case OMPC_acquire:
17533
1.91k
    Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
17534
1.91k
    break;
17535
1.94k
  case OMPC_release:
17536
1.94k
    Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
17537
1.94k
    break;
17538
1.95k
  case OMPC_relaxed:
17539
1.95k
    Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
17540
1.95k
    break;
17541
153
  case OMPC_threads:
17542
153
    Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
17543
153
    break;
17544
140
  case OMPC_simd:
17545
140
    Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
17546
140
    break;
17547
352
  case OMPC_nogroup:
17548
352
    Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
17549
352
    break;
17550
27
  case OMPC_unified_address:
17551
27
    Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
17552
27
    break;
17553
39
  case OMPC_unified_shared_memory:
17554
39
    Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17555
39
    break;
17556
17
  case OMPC_reverse_offload:
17557
17
    Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
17558
17
    break;
17559
150
  case OMPC_dynamic_allocators:
17560
150
    Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
17561
150
    break;
17562
58
  case OMPC_destroy:
17563
58
    Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
17564
58
                                   /*LParenLoc=*/SourceLocation(),
17565
58
                                   /*VarLoc=*/SourceLocation(), EndLoc);
17566
58
    break;
17567
15
  case OMPC_full:
17568
15
    Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
17569
15
    break;
17570
31
  case OMPC_partial:
17571
31
    Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
17572
31
    break;
17573
46
  case OMPC_ompx_bare:
17574
46
    Res = ActOnOpenMPXBareClause(StartLoc, EndLoc);
17575
46
    break;
17576
0
  case OMPC_if:
17577
0
  case OMPC_final:
17578
0
  case OMPC_num_threads:
17579
0
  case OMPC_safelen:
17580
0
  case OMPC_simdlen:
17581
0
  case OMPC_sizes:
17582
0
  case OMPC_allocator:
17583
0
  case OMPC_collapse:
17584
0
  case OMPC_schedule:
17585
0
  case OMPC_private:
17586
0
  case OMPC_firstprivate:
17587
0
  case OMPC_lastprivate:
17588
0
  case OMPC_shared:
17589
0
  case OMPC_reduction:
17590
0
  case OMPC_task_reduction:
17591
0
  case OMPC_in_reduction:
17592
0
  case OMPC_linear:
17593
0
  case OMPC_aligned:
17594
0
  case OMPC_copyin:
17595
0
  case OMPC_copyprivate:
17596
0
  case OMPC_default:
17597
0
  case OMPC_proc_bind:
17598
0
  case OMPC_threadprivate:
17599
0
  case OMPC_allocate:
17600
0
  case OMPC_flush:
17601
0
  case OMPC_depobj:
17602
0
  case OMPC_depend:
17603
0
  case OMPC_device:
17604
0
  case OMPC_map:
17605
0
  case OMPC_num_teams:
17606
0
  case OMPC_thread_limit:
17607
0
  case OMPC_priority:
17608
0
  case OMPC_grainsize:
17609
0
  case OMPC_num_tasks:
17610
0
  case OMPC_hint:
17611
0
  case OMPC_dist_schedule:
17612
0
  case OMPC_defaultmap:
17613
0
  case OMPC_unknown:
17614
0
  case OMPC_uniform:
17615
0
  case OMPC_to:
17616
0
  case OMPC_from:
17617
0
  case OMPC_use_device_ptr:
17618
0
  case OMPC_use_device_addr:
17619
0
  case OMPC_is_device_ptr:
17620
0
  case OMPC_has_device_addr:
17621
0
  case OMPC_atomic_default_mem_order:
17622
0
  case OMPC_device_type:
17623
0
  case OMPC_match:
17624
0
  case OMPC_nontemporal:
17625
0
  case OMPC_order:
17626
0
  case OMPC_at:
17627
0
  case OMPC_severity:
17628
0
  case OMPC_message:
17629
0
  case OMPC_novariants:
17630
0
  case OMPC_nocontext:
17631
0
  case OMPC_detach:
17632
0
  case OMPC_inclusive:
17633
0
  case OMPC_exclusive:
17634
0
  case OMPC_uses_allocators:
17635
0
  case OMPC_affinity:
17636
0
  case OMPC_when:
17637
0
  case OMPC_ompx_dyn_cgroup_mem:
17638
0
  default:
17639
0
    llvm_unreachable("Clause is not allowed.");
17640
35.5k
  }
17641
35.5k
  return Res;
17642
35.5k
}
17643
17644
OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
17645
1.82k
                                         SourceLocation EndLoc) {
17646
1.82k
  DSAStack->setNowaitRegion();
17647
1.82k
  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
17648
1.82k
}
17649
17650
OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
17651
148
                                         SourceLocation EndLoc) {
17652
148
  DSAStack->setUntiedRegion();
17653
148
  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
17654
148
}
17655
17656
OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
17657
168
                                            SourceLocation EndLoc) {
17658
168
  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
17659
168
}
17660
17661
OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
17662
531
                                       SourceLocation EndLoc) {
17663
531
  return new (Context) OMPReadClause(StartLoc, EndLoc);
17664
531
}
17665
17666
OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
17667
524
                                        SourceLocation EndLoc) {
17668
524
  return new (Context) OMPWriteClause(StartLoc, EndLoc);
17669
524
}
17670
17671
OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
17672
635
                                         SourceLocation EndLoc) {
17673
635
  return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
17674
635
}
17675
17676
OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
17677
9.40k
                                          SourceLocation EndLoc) {
17678
9.40k
  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
17679
9.40k
}
17680
17681
OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
17682
10.9k
                                          SourceLocation EndLoc) {
17683
10.9k
  return new (Context) OMPCompareClause(StartLoc, EndLoc);
17684
10.9k
}
17685
17686
OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
17687
2.07k
                                         SourceLocation EndLoc) {
17688
2.07k
  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
17689
2.07k
}
17690
17691
OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
17692
1.89k
                                         SourceLocation EndLoc) {
17693
1.89k
  return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
17694
1.89k
}
17695
17696
OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
17697
1.91k
                                          SourceLocation EndLoc) {
17698
1.91k
  return new (Context) OMPAcquireClause(StartLoc, EndLoc);
17699
1.91k
}
17700
17701
OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
17702
1.94k
                                          SourceLocation EndLoc) {
17703
1.94k
  return new (Context) OMPReleaseClause(StartLoc, EndLoc);
17704
1.94k
}
17705
17706
OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
17707
1.95k
                                          SourceLocation EndLoc) {
17708
1.95k
  return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
17709
1.95k
}
17710
17711
OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
17712
153
                                          SourceLocation EndLoc) {
17713
153
  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
17714
153
}
17715
17716
OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
17717
140
                                       SourceLocation EndLoc) {
17718
140
  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
17719
140
}
17720
17721
OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
17722
352
                                          SourceLocation EndLoc) {
17723
352
  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
17724
352
}
17725
17726
OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
17727
27
                                                 SourceLocation EndLoc) {
17728
27
  return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
17729
27
}
17730
17731
OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
17732
39
                                                      SourceLocation EndLoc) {
17733
39
  return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17734
39
}
17735
17736
OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
17737
17
                                                 SourceLocation EndLoc) {
17738
17
  return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
17739
17
}
17740
17741
OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
17742
150
                                                    SourceLocation EndLoc) {
17743
150
  return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
17744
150
}
17745
17746
StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
17747
                                             SourceLocation StartLoc,
17748
218
                                             SourceLocation EndLoc) {
17749
17750
  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17751
  // At least one action-clause must appear on a directive.
17752
218
  if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17753
1
    StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
17754
1
    Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17755
1
        << Expected << getOpenMPDirectiveName(OMPD_interop);
17756
1
    return StmtError();
17757
1
  }
17758
17759
  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17760
  // A depend clause can only appear on the directive if a targetsync
17761
  // interop-type is present or the interop-var was initialized with
17762
  // the targetsync interop-type.
17763
17764
  // If there is any 'init' clause diagnose if there is no 'init' clause with
17765
  // interop-type of 'targetsync'. Cases involving other directives cannot be
17766
  // diagnosed.
17767
217
  const OMPDependClause *DependClause = nullptr;
17768
217
  bool HasInitClause = false;
17769
217
  bool IsTargetSync = false;
17770
314
  for (const OMPClause *C : Clauses) {
17771
314
    if (IsTargetSync)
17772
2
      break;
17773
312
    if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
17774
137
      HasInitClause = true;
17775
137
      if (InitClause->getIsTargetSync())
17776
29
        IsTargetSync = true;
17777
175
    } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
17778
23
      DependClause = DC;
17779
23
    }
17780
312
  }
17781
217
  if (DependClause && 
HasInitClause19
&&
!IsTargetSync5
) {
17782
1
    Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17783
1
    return StmtError();
17784
1
  }
17785
17786
  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17787
  // Each interop-var may be specified for at most one action-clause of each
17788
  // interop construct.
17789
216
  llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars;
17790
312
  for (OMPClause *C : Clauses) {
17791
312
    OpenMPClauseKind ClauseKind = C->getClauseKind();
17792
312
    std::pair<ValueDecl *, bool> DeclResult;
17793
312
    SourceLocation ELoc;
17794
312
    SourceRange ERange;
17795
17796
312
    if (ClauseKind == OMPC_init) {
17797
136
      auto *E = cast<OMPInitClause>(C)->getInteropVar();
17798
136
      DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17799
176
    } else if (ClauseKind == OMPC_use) {
17800
65
      auto *E = cast<OMPUseClause>(C)->getInteropVar();
17801
65
      DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17802
111
    } else if (ClauseKind == OMPC_destroy) {
17803
64
      auto *E = cast<OMPDestroyClause>(C)->getInteropVar();
17804
64
      DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17805
64
    }
17806
17807
312
    if (DeclResult.first) {
17808
253
      if (!InteropVars.insert(DeclResult.first).second) {
17809
12
        Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
17810
12
            << DeclResult.first;
17811
12
        return StmtError();
17812
12
      }
17813
253
    }
17814
312
  }
17815
17816
204
  return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
17817
216
}
17818
17819
static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
17820
                                   SourceLocation VarLoc,
17821
289
                                   OpenMPClauseKind Kind) {
17822
289
  SourceLocation ELoc;
17823
289
  SourceRange ERange;
17824
289
  Expr *RefExpr = InteropVarExpr;
17825
289
  auto Res =
17826
289
      getPrivateItem(SemaRef, RefExpr, ELoc, ERange,
17827
289
                     /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
17828
17829
289
  if (Res.second) {
17830
    // It will be analyzed later.
17831
12
    return true;
17832
12
  }
17833
17834
277
  if (!Res.first)
17835
10
    return false;
17836
17837
  // Interop variable should be of type omp_interop_t.
17838
267
  bool HasError = false;
17839
267
  QualType InteropType;
17840
267
  LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
17841
267
                      VarLoc, Sema::LookupOrdinaryName);
17842
267
  if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
17843
264
    NamedDecl *ND = Result.getFoundDecl();
17844
264
    if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
17845
264
      InteropType = QualType(TD->getTypeForDecl(), 0);
17846
264
    } else {
17847
0
      HasError = true;
17848
0
    }
17849
264
  } else {
17850
3
    HasError = true;
17851
3
  }
17852
17853
267
  if (HasError) {
17854
3
    SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
17855
3
        << "omp_interop_t";
17856
3
    return false;
17857
3
  }
17858
17859
264
  QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
17860
264
  if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
17861
6
    SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17862
6
    return false;
17863
6
  }
17864
17865
  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17866
  // The interop-var passed to init or destroy must be non-const.
17867
258
  if ((Kind == OMPC_init || 
Kind == OMPC_destroy122
) &&
17868
258
      
isConstNotMutableType(SemaRef, InteropVarExpr->getType())197
) {
17869
2
    SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
17870
2
        << /*non-const*/ 1;
17871
2
    return false;
17872
2
  }
17873
256
  return true;
17874
258
}
17875
17876
OMPClause *
17877
Sema::ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
17878
                            SourceLocation StartLoc, SourceLocation LParenLoc,
17879
151
                            SourceLocation VarLoc, SourceLocation EndLoc) {
17880
17881
151
  if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
17882
12
    return nullptr;
17883
17884
  // Check prefer_type values.  These foreign-runtime-id values are either
17885
  // string literals or constant integral expressions.
17886
139
  for (const Expr *E : InteropInfo.PreferTypes) {
17887
123
    if (E->isValueDependent() || 
E->isTypeDependent()119
||
17888
123
        
E->isInstantiationDependent()119
||
E->containsUnexpandedParameterPack()119
)
17889
4
      continue;
17890
119
    if (E->isIntegerConstantExpr(Context))
17891
71
      continue;
17892
48
    if (isa<StringLiteral>(E))
17893
46
      continue;
17894
2
    Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
17895
2
    return nullptr;
17896
48
  }
17897
17898
137
  return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc,
17899
137
                               LParenLoc, VarLoc, EndLoc);
17900
139
}
17901
17902
OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
17903
                                      SourceLocation LParenLoc,
17904
                                      SourceLocation VarLoc,
17905
69
                                      SourceLocation EndLoc) {
17906
17907
69
  if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
17908
4
    return nullptr;
17909
17910
65
  return new (Context)
17911
65
      OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17912
69
}
17913
17914
OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
17915
                                          SourceLocation StartLoc,
17916
                                          SourceLocation LParenLoc,
17917
                                          SourceLocation VarLoc,
17918
139
                                          SourceLocation EndLoc) {
17919
139
  if (!InteropVar && 
LangOpts.OpenMP >= 5270
&&
17920
139
      
DSAStack14
->getCurrentDirective() == OMPD_depobj14
) {
17921
14
    Diag(StartLoc, diag::err_omp_expected_clause_argument)
17922
14
        << getOpenMPClauseName(OMPC_destroy)
17923
14
        << getOpenMPDirectiveName(OMPD_depobj);
17924
14
    return nullptr;
17925
14
  }
17926
125
  if (InteropVar &&
17927
125
      
!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)69
)
17928
5
    return nullptr;
17929
17930
120
  return new (Context)
17931
120
      OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17932
125
}
17933
17934
OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
17935
                                             SourceLocation StartLoc,
17936
                                             SourceLocation LParenLoc,
17937
16
                                             SourceLocation EndLoc) {
17938
16
  Expr *ValExpr = Condition;
17939
16
  Stmt *HelperValStmt = nullptr;
17940
16
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17941
16
  if (!Condition->isValueDependent() && 
!Condition->isTypeDependent()14
&&
17942
16
      
!Condition->isInstantiationDependent()14
&&
17943
16
      
!Condition->containsUnexpandedParameterPack()14
) {
17944
14
    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17945
14
    if (Val.isInvalid())
17946
0
      return nullptr;
17947
17948
14
    ValExpr = MakeFullExpr(Val.get()).get();
17949
17950
14
    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17951
14
    CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
17952
14
                                                    LangOpts.OpenMP);
17953
14
    if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17954
14
      ValExpr = MakeFullExpr(ValExpr).get();
17955
14
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17956
14
      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17957
14
      HelperValStmt = buildPreInits(Context, Captures);
17958
14
    }
17959
14
  }
17960
17961
16
  return new (Context) OMPNovariantsClause(
17962
16
      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
17963
16
}
17964
17965
OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
17966
                                            SourceLocation StartLoc,
17967
                                            SourceLocation LParenLoc,
17968
16
                                            SourceLocation EndLoc) {
17969
16
  Expr *ValExpr = Condition;
17970
16
  Stmt *HelperValStmt = nullptr;
17971
16
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17972
16
  if (!Condition->isValueDependent() && 
!Condition->isTypeDependent()14
&&
17973
16
      
!Condition->isInstantiationDependent()14
&&
17974
16
      
!Condition->containsUnexpandedParameterPack()14
) {
17975
14
    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17976
14
    if (Val.isInvalid())
17977
0
      return nullptr;
17978
17979
14
    ValExpr = MakeFullExpr(Val.get()).get();
17980
17981
14
    OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17982
14
    CaptureRegion =
17983
14
        getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
17984
14
    if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17985
14
      ValExpr = MakeFullExpr(ValExpr).get();
17986
14
      llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17987
14
      ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17988
14
      HelperValStmt = buildPreInits(Context, Captures);
17989
14
    }
17990
14
  }
17991
17992
16
  return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
17993
16
                                          StartLoc, LParenLoc, EndLoc);
17994
16
}
17995
17996
OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
17997
                                         SourceLocation StartLoc,
17998
                                         SourceLocation LParenLoc,
17999
313
                                         SourceLocation EndLoc) {
18000
313
  Expr *ValExpr = ThreadID;
18001
313
  Stmt *HelperValStmt = nullptr;
18002
18003
313
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18004
313
  OpenMPDirectiveKind CaptureRegion =
18005
313
      getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
18006
313
  if (CaptureRegion != OMPD_unknown && 
!CurContext->isDependentContext()0
) {
18007
0
    ValExpr = MakeFullExpr(ValExpr).get();
18008
0
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18009
0
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18010
0
    HelperValStmt = buildPreInits(Context, Captures);
18011
0
  }
18012
18013
313
  return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
18014
313
                                       StartLoc, LParenLoc, EndLoc);
18015
313
}
18016
18017
OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
18018
                                          ArrayRef<Expr *> VarList,
18019
                                          const OMPVarListLocTy &Locs,
18020
149k
                                          OpenMPVarListDataTy &Data) {
18021
149k
  SourceLocation StartLoc = Locs.StartLoc;
18022
149k
  SourceLocation LParenLoc = Locs.LParenLoc;
18023
149k
  SourceLocation EndLoc = Locs.EndLoc;
18024
149k
  OMPClause *Res = nullptr;
18025
149k
  int ExtraModifier = Data.ExtraModifier;
18026
149k
  SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
18027
149k
  SourceLocation ColonLoc = Data.ColonLoc;
18028
149k
  switch (Kind) {
18029
14.5k
  case OMPC_private:
18030
14.5k
    Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18031
14.5k
    break;
18032
6.90k
  case OMPC_firstprivate:
18033
6.90k
    Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18034
6.90k
    break;
18035
7.14k
  case OMPC_lastprivate:
18036
7.14k
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
18037
7.14k
           "Unexpected lastprivate modifier.");
18038
7.14k
    Res = ActOnOpenMPLastprivateClause(
18039
7.14k
        VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
18040
7.14k
        ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
18041
7.14k
    break;
18042
4.44k
  case OMPC_shared:
18043
4.44k
    Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
18044
4.44k
    break;
18045
57.2k
  case OMPC_reduction:
18046
57.2k
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
18047
57.2k
           "Unexpected lastprivate modifier.");
18048
57.2k
    Res = ActOnOpenMPReductionClause(
18049
57.2k
        VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
18050
57.2k
        StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
18051
57.2k
        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18052
57.2k
    break;
18053
4.48k
  case OMPC_task_reduction:
18054
4.48k
    Res = ActOnOpenMPTaskReductionClause(
18055
4.48k
        VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18056
4.48k
        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18057
4.48k
    break;
18058
6.78k
  case OMPC_in_reduction:
18059
6.78k
    Res = ActOnOpenMPInReductionClause(
18060
6.78k
        VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18061
6.78k
        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18062
6.78k
    break;
18063
4.70k
  case OMPC_linear:
18064
4.70k
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
18065
4.70k
           "Unexpected linear modifier.");
18066
4.70k
    Res = ActOnOpenMPLinearClause(
18067
4.70k
        VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
18068
4.70k
        static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
18069
4.70k
        ColonLoc, Data.StepModifierLoc, EndLoc);
18070
4.70k
    break;
18071
2.40k
  case OMPC_aligned:
18072
2.40k
    Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
18073
2.40k
                                   LParenLoc, ColonLoc, EndLoc);
18074
2.40k
    break;
18075
442
  case OMPC_copyin:
18076
442
    Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
18077
442
    break;
18078
128
  case OMPC_copyprivate:
18079
128
    Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18080
128
    break;
18081
56
  case OMPC_flush:
18082
56
    Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
18083
56
    break;
18084
6.09k
  case OMPC_depend:
18085
6.09k
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
18086
6.09k
           "Unexpected depend modifier.");
18087
6.09k
    Res = ActOnOpenMPDependClause(
18088
6.09k
        {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc,
18089
6.09k
         ColonLoc, Data.OmpAllMemoryLoc},
18090
6.09k
        Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
18091
6.09k
    break;
18092
24.6k
  case OMPC_map:
18093
24.6k
    assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
18094
24.6k
           "Unexpected map modifier.");
18095
24.6k
    Res = ActOnOpenMPMapClause(
18096
24.6k
        Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
18097
24.6k
        Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
18098
24.6k
        static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
18099
24.6k
        ExtraModifierLoc, ColonLoc, VarList, Locs);
18100
24.6k
    break;
18101
2.21k
  case OMPC_to:
18102
2.21k
    Res =
18103
2.21k
        ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc,
18104
2.21k
                            Data.ReductionOrMapperIdScopeSpec,
18105
2.21k
                            Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
18106
2.21k
    break;
18107
988
  case OMPC_from:
18108
988
    Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc,
18109
988
                                Data.ReductionOrMapperIdScopeSpec,
18110
988
                                Data.ReductionOrMapperId, ColonLoc, VarList,
18111
988
                                Locs);
18112
988
    break;
18113
340
  case OMPC_use_device_ptr:
18114
340
    Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
18115
340
    break;
18116
100
  case OMPC_use_device_addr:
18117
100
    Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
18118
100
    break;
18119
2.73k
  case OMPC_is_device_ptr:
18120
2.73k
    Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
18121
2.73k
    break;
18122
251
  case OMPC_has_device_addr:
18123
251
    Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
18124
251
    break;
18125
1.60k
  case OMPC_allocate:
18126
1.60k
    Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
18127
1.60k
                                    LParenLoc, ColonLoc, EndLoc);
18128
1.60k
    break;
18129
734
  case OMPC_nontemporal:
18130
734
    Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
18131
734
    break;
18132
124
  case OMPC_inclusive:
18133
124
    Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
18134
124
    break;
18135
113
  case OMPC_exclusive:
18136
113
    Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
18137
113
    break;
18138
70
  case OMPC_affinity:
18139
70
    Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
18140
70
                                    Data.DepModOrTailExpr, VarList);
18141
70
    break;
18142
96
  case OMPC_doacross:
18143
96
    Res = ActOnOpenMPDoacrossClause(
18144
96
        static_cast<OpenMPDoacrossClauseModifier>(ExtraModifier),
18145
96
        ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
18146
96
    break;
18147
0
  case OMPC_if:
18148
0
  case OMPC_depobj:
18149
0
  case OMPC_final:
18150
0
  case OMPC_num_threads:
18151
0
  case OMPC_safelen:
18152
0
  case OMPC_simdlen:
18153
0
  case OMPC_sizes:
18154
0
  case OMPC_allocator:
18155
0
  case OMPC_collapse:
18156
0
  case OMPC_default:
18157
0
  case OMPC_proc_bind:
18158
0
  case OMPC_schedule:
18159
0
  case OMPC_ordered:
18160
0
  case OMPC_nowait:
18161
0
  case OMPC_untied:
18162
0
  case OMPC_mergeable:
18163
0
  case OMPC_threadprivate:
18164
0
  case OMPC_read:
18165
0
  case OMPC_write:
18166
0
  case OMPC_update:
18167
0
  case OMPC_capture:
18168
0
  case OMPC_compare:
18169
0
  case OMPC_seq_cst:
18170
0
  case OMPC_acq_rel:
18171
0
  case OMPC_acquire:
18172
0
  case OMPC_release:
18173
0
  case OMPC_relaxed:
18174
0
  case OMPC_device:
18175
0
  case OMPC_threads:
18176
0
  case OMPC_simd:
18177
0
  case OMPC_num_teams:
18178
0
  case OMPC_thread_limit:
18179
0
  case OMPC_priority:
18180
0
  case OMPC_grainsize:
18181
0
  case OMPC_nogroup:
18182
0
  case OMPC_num_tasks:
18183
0
  case OMPC_hint:
18184
0
  case OMPC_dist_schedule:
18185
0
  case OMPC_defaultmap:
18186
0
  case OMPC_unknown:
18187
0
  case OMPC_uniform:
18188
0
  case OMPC_unified_address:
18189
0
  case OMPC_unified_shared_memory:
18190
0
  case OMPC_reverse_offload:
18191
0
  case OMPC_dynamic_allocators:
18192
0
  case OMPC_atomic_default_mem_order:
18193
0
  case OMPC_device_type:
18194
0
  case OMPC_match:
18195
0
  case OMPC_order:
18196
0
  case OMPC_at:
18197
0
  case OMPC_severity:
18198
0
  case OMPC_message:
18199
0
  case OMPC_destroy:
18200
0
  case OMPC_novariants:
18201
0
  case OMPC_nocontext:
18202
0
  case OMPC_detach:
18203
0
  case OMPC_uses_allocators:
18204
0
  case OMPC_when:
18205
0
  case OMPC_bind:
18206
0
  default:
18207
0
    llvm_unreachable("Clause is not allowed.");
18208
149k
  }
18209
149k
  return Res;
18210
149k
}
18211
18212
ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
18213
2.77k
                                       ExprObjectKind OK, SourceLocation Loc) {
18214
2.77k
  ExprResult Res = BuildDeclRefExpr(
18215
2.77k
      Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
18216
2.77k
  if (!Res.isUsable())
18217
0
    return ExprError();
18218
2.77k
  if (OK == OK_Ordinary && 
!getLangOpts().CPlusPlus2.58k
) {
18219
0
    Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
18220
0
    if (!Res.isUsable())
18221
0
      return ExprError();
18222
0
  }
18223
2.77k
  if (VK != VK_LValue && 
Res.get()->isGLValue()0
) {
18224
0
    Res = DefaultLvalueConversion(Res.get());
18225
0
    if (!Res.isUsable())
18226
0
      return ExprError();
18227
0
  }
18228
2.77k
  return Res;
18229
2.77k
}
18230
18231
OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
18232
                                          SourceLocation StartLoc,
18233
                                          SourceLocation LParenLoc,
18234
22.8k
                                          SourceLocation EndLoc) {
18235
22.8k
  SmallVector<Expr *, 8> Vars;
18236
22.8k
  SmallVector<Expr *, 8> PrivateCopies;
18237
22.8k
  bool IsImplicitClause =
18238
22.8k
      StartLoc.isInvalid() && 
LParenLoc.isInvalid()28
&&
EndLoc.isInvalid()28
;
18239
28.4k
  for (Expr *RefExpr : VarList) {
18240
28.4k
    assert(RefExpr && "NULL expr in OpenMP private clause.");
18241
28.4k
    SourceLocation ELoc;
18242
28.4k
    SourceRange ERange;
18243
28.4k
    Expr *SimpleRefExpr = RefExpr;
18244
28.4k
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18245
28.4k
    if (Res.second) {
18246
      // It will be analyzed later.
18247
6.34k
      Vars.push_back(RefExpr);
18248
6.34k
      PrivateCopies.push_back(nullptr);
18249
6.34k
    }
18250
28.4k
    ValueDecl *D = Res.first;
18251
28.4k
    if (!D)
18252
6.92k
      continue;
18253
18254
21.5k
    QualType Type = D->getType();
18255
21.5k
    auto *VD = dyn_cast<VarDecl>(D);
18256
18257
    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18258
    //  A variable that appears in a private clause must not have an incomplete
18259
    //  type or a reference type.
18260
21.5k
    if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
18261
144
      continue;
18262
21.4k
    Type = Type.getNonReferenceType();
18263
18264
    // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18265
    // A variable that is privatized must not have a const-qualified type
18266
    // unless it is of class type with a mutable member. This restriction does
18267
    // not apply to the firstprivate clause.
18268
    //
18269
    // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
18270
    // A variable that appears in a private clause must not have a
18271
    // const-qualified type unless it is of class type with a mutable member.
18272
21.4k
    if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
18273
160
      continue;
18274
18275
    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18276
    // in a Construct]
18277
    //  Variables with the predetermined data-sharing attributes may not be
18278
    //  listed in data-sharing attributes clauses, except for the cases
18279
    //  listed below. For these exceptions only, listing a predetermined
18280
    //  variable in a data-sharing attribute clause is allowed and overrides
18281
    //  the variable's predetermined data-sharing attributes.
18282
21.2k
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18283
21.2k
    if (DVar.CKind != OMPC_unknown && 
DVar.CKind != OMPC_private1.82k
) {
18284
313
      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18285
313
                                          << getOpenMPClauseName(OMPC_private);
18286
313
      reportOriginalDsa(*this, DSAStack, D, DVar);
18287
313
      continue;
18288
313
    }
18289
18290
20.9k
    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18291
    // Variably modified types are not supported for tasks.
18292
20.9k
    if (!Type->isAnyPointerType() && 
Type->isVariablyModifiedType()20.5k
&&
18293
20.9k
        
isOpenMPTaskingDirective(CurrDir)52
) {
18294
0
      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18295
0
          << getOpenMPClauseName(OMPC_private) << Type
18296
0
          << getOpenMPDirectiveName(CurrDir);
18297
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18298
0
                               VarDecl::DeclarationOnly;
18299
0
      Diag(D->getLocation(),
18300
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18301
0
          << D;
18302
0
      continue;
18303
0
    }
18304
18305
    // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18306
    // A list item cannot appear in both a map clause and a data-sharing
18307
    // attribute clause on the same construct
18308
    //
18309
    // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18310
    // A list item cannot appear in both a map clause and a data-sharing
18311
    // attribute clause on the same construct unless the construct is a
18312
    // combined construct.
18313
20.9k
    if ((LangOpts.OpenMP <= 45 && 
isOpenMPTargetExecutionDirective(CurrDir)3.31k
) ||
18314
20.9k
        
CurrDir == OMPD_target20.3k
) {
18315
1.06k
      OpenMPClauseKind ConflictKind;
18316
1.06k
      if (DSAStack->checkMappableExprComponentListsForDecl(
18317
1.06k
              VD, /*CurrentRegionOnly=*/true,
18318
1.06k
              [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
18319
1.06k
                  OpenMPClauseKind WhereFoundClauseKind) -> bool {
18320
38
                ConflictKind = WhereFoundClauseKind;
18321
38
                return true;
18322
38
              })) {
18323
38
        Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18324
38
            << getOpenMPClauseName(OMPC_private)
18325
38
            << getOpenMPClauseName(ConflictKind)
18326
38
            << getOpenMPDirectiveName(CurrDir);
18327
38
        reportOriginalDsa(*this, DSAStack, D, DVar);
18328
38
        continue;
18329
38
      }
18330
1.06k
    }
18331
18332
    // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
18333
    //  A variable of class type (or array thereof) that appears in a private
18334
    //  clause requires an accessible, unambiguous default constructor for the
18335
    //  class type.
18336
    // Generate helper private variable and initialize it with the default
18337
    // value. The address of the original variable is replaced by the address of
18338
    // the new private variable in CodeGen. This new variable is not added to
18339
    // IdResolver, so the code in the OpenMP region uses original variable for
18340
    // proper diagnostics.
18341
20.9k
    Type = Type.getUnqualifiedType();
18342
20.9k
    VarDecl *VDPrivate =
18343
20.9k
        buildVarDecl(*this, ELoc, Type, D->getName(),
18344
20.9k
                     D->hasAttrs() ? 
&D->getAttrs()91
:
nullptr20.8k
,
18345
20.9k
                     VD ? 
cast<DeclRefExpr>(SimpleRefExpr)18.1k
:
nullptr2.72k
);
18346
20.9k
    ActOnUninitializedDecl(VDPrivate);
18347
20.9k
    if (VDPrivate->isInvalidDecl())
18348
0
      continue;
18349
20.9k
    DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18350
20.9k
        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18351
18352
20.9k
    DeclRefExpr *Ref = nullptr;
18353
20.9k
    if (!VD && 
!CurContext->isDependentContext()2.72k
) {
18354
2.72k
      auto *FD = dyn_cast<FieldDecl>(D);
18355
2.72k
      VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : 
nullptr0
;
18356
2.72k
      if (VD)
18357
10
        Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18358
10
                               RefExpr->getExprLoc());
18359
2.71k
      else
18360
2.71k
        Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18361
2.72k
    }
18362
20.9k
    if (!IsImplicitClause)
18363
20.8k
      DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18364
20.9k
    Vars.push_back((VD || 
CurContext->isDependentContext()2.72k
)
18365
20.9k
                       ? 
RefExpr->IgnoreParens()18.1k
18366
20.9k
                       : 
Ref2.72k
);
18367
20.9k
    PrivateCopies.push_back(VDPrivateRefExpr);
18368
20.9k
  }
18369
18370
22.8k
  if (Vars.empty())
18371
952
    return nullptr;
18372
18373
21.9k
  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
18374
21.9k
                                  PrivateCopies);
18375
22.8k
}
18376
18377
OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
18378
                                               SourceLocation StartLoc,
18379
                                               SourceLocation LParenLoc,
18380
66.0k
                                               SourceLocation EndLoc) {
18381
66.0k
  SmallVector<Expr *, 8> Vars;
18382
66.0k
  SmallVector<Expr *, 8> PrivateCopies;
18383
66.0k
  SmallVector<Expr *, 8> Inits;
18384
66.0k
  SmallVector<Decl *, 4> ExprCaptures;
18385
66.0k
  bool IsImplicitClause =
18386
66.0k
      StartLoc.isInvalid() && 
LParenLoc.isInvalid()57.5k
&&
EndLoc.isInvalid()57.5k
;
18387
66.0k
  SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
18388
18389
83.8k
  for (Expr *RefExpr : VarList) {
18390
83.8k
    assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
18391
83.8k
    SourceLocation ELoc;
18392
83.8k
    SourceRange ERange;
18393
83.8k
    Expr *SimpleRefExpr = RefExpr;
18394
83.8k
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18395
83.8k
    if (Res.second) {
18396
      // It will be analyzed later.
18397
2.55k
      Vars.push_back(RefExpr);
18398
2.55k
      PrivateCopies.push_back(nullptr);
18399
2.55k
      Inits.push_back(nullptr);
18400
2.55k
    }
18401
83.8k
    ValueDecl *D = Res.first;
18402
83.8k
    if (!D)
18403
2.97k
      continue;
18404
18405
80.8k
    ELoc = IsImplicitClause ? 
ImplicitClauseLoc70.2k
:
ELoc10.6k
;
18406
80.8k
    QualType Type = D->getType();
18407
80.8k
    auto *VD = dyn_cast<VarDecl>(D);
18408
18409
    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18410
    //  A variable that appears in a private clause must not have an incomplete
18411
    //  type or a reference type.
18412
80.8k
    if (RequireCompleteType(ELoc, Type,
18413
80.8k
                            diag::err_omp_firstprivate_incomplete_type))
18414
140
      continue;
18415
80.7k
    Type = Type.getNonReferenceType();
18416
18417
    // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
18418
    //  A variable of class type (or array thereof) that appears in a private
18419
    //  clause requires an accessible, unambiguous copy constructor for the
18420
    //  class type.
18421
80.7k
    QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
18422
18423
    // If an implicit firstprivate variable found it was checked already.
18424
80.7k
    DSAStackTy::DSAVarData TopDVar;
18425
80.7k
    if (!IsImplicitClause) {
18426
10.4k
      DSAStackTy::DSAVarData DVar =
18427
10.4k
          DSAStack->getTopDSA(D, /*FromParent=*/false);
18428
10.4k
      TopDVar = DVar;
18429
10.4k
      OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18430
10.4k
      bool IsConstant = ElemType.isConstant(Context);
18431
      // OpenMP [2.4.13, Data-sharing Attribute Clauses]
18432
      //  A list item that specifies a given variable may not appear in more
18433
      // than one clause on the same directive, except that a variable may be
18434
      //  specified in both firstprivate and lastprivate clauses.
18435
      // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18436
      // A list item may appear in a firstprivate or lastprivate clause but not
18437
      // both.
18438
10.4k
      if (DVar.CKind != OMPC_unknown && 
DVar.CKind != OMPC_firstprivate1.60k
&&
18439
10.4k
          
(1.29k
isOpenMPDistributeDirective(CurrDir)1.29k
||
18440
1.29k
           
DVar.CKind != OMPC_lastprivate906
) &&
18441
10.4k
          
DVar.RefExpr708
) {
18442
536
        Diag(ELoc, diag::err_omp_wrong_dsa)
18443
536
            << getOpenMPClauseName(DVar.CKind)
18444
536
            << getOpenMPClauseName(OMPC_firstprivate);
18445
536
        reportOriginalDsa(*this, DSAStack, D, DVar);
18446
536
        continue;
18447
536
      }
18448
18449
      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18450
      // in a Construct]
18451
      //  Variables with the predetermined data-sharing attributes may not be
18452
      //  listed in data-sharing attributes clauses, except for the cases
18453
      //  listed below. For these exceptions only, listing a predetermined
18454
      //  variable in a data-sharing attribute clause is allowed and overrides
18455
      //  the variable's predetermined data-sharing attributes.
18456
      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18457
      // in a Construct, C/C++, p.2]
18458
      //  Variables with const-qualified type having no mutable member may be
18459
      //  listed in a firstprivate clause, even if they are static data members.
18460
9.94k
      if (!(IsConstant || 
(9.01k
VD9.01k
&&
VD->isStaticDataMember()8.62k
)) &&
!DVar.RefExpr8.93k
&&
18461
9.94k
          
DVar.CKind != OMPC_unknown8.03k
&&
DVar.CKind != OMPC_shared0
) {
18462
0
        Diag(ELoc, diag::err_omp_wrong_dsa)
18463
0
            << getOpenMPClauseName(DVar.CKind)
18464
0
            << getOpenMPClauseName(OMPC_firstprivate);
18465
0
        reportOriginalDsa(*this, DSAStack, D, DVar);
18466
0
        continue;
18467
0
      }
18468
18469
      // OpenMP [2.9.3.4, Restrictions, p.2]
18470
      //  A list item that is private within a parallel region must not appear
18471
      //  in a firstprivate clause on a worksharing construct if any of the
18472
      //  worksharing regions arising from the worksharing construct ever bind
18473
      //  to any of the parallel regions arising from the parallel construct.
18474
      // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18475
      // A list item that is private within a teams region must not appear in a
18476
      // firstprivate clause on a distribute construct if any of the distribute
18477
      // regions arising from the distribute construct ever bind to any of the
18478
      // teams regions arising from the teams construct.
18479
      // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18480
      // A list item that appears in a reduction clause of a teams construct
18481
      // must not appear in a firstprivate clause on a distribute construct if
18482
      // any of the distribute regions arising from the distribute construct
18483
      // ever bind to any of the teams regions arising from the teams construct.
18484
9.94k
      if ((isOpenMPWorksharingDirective(CurrDir) ||
18485
9.94k
           
isOpenMPDistributeDirective(CurrDir)6.17k
) &&
18486
9.94k
          
!isOpenMPParallelDirective(CurrDir)5.26k
&&
18487
9.94k
          
!isOpenMPTeamsDirective(CurrDir)2.34k
) {
18488
1.36k
        DVar = DSAStack->getImplicitDSA(D, true);
18489
1.36k
        if (DVar.CKind != OMPC_shared &&
18490
1.36k
            
(54
isOpenMPParallelDirective(DVar.DKind)54
||
18491
54
             
isOpenMPTeamsDirective(DVar.DKind)22
||
18492
54
             
DVar.DKind == OMPD_unknown18
)) {
18493
54
          Diag(ELoc, diag::err_omp_required_access)
18494
54
              << getOpenMPClauseName(OMPC_firstprivate)
18495
54
              << getOpenMPClauseName(OMPC_shared);
18496
54
          reportOriginalDsa(*this, DSAStack, D, DVar);
18497
54
          continue;
18498
54
        }
18499
1.36k
      }
18500
      // OpenMP [2.9.3.4, Restrictions, p.3]
18501
      //  A list item that appears in a reduction clause of a parallel construct
18502
      //  must not appear in a firstprivate clause on a worksharing or task
18503
      //  construct if any of the worksharing or task regions arising from the
18504
      //  worksharing or task construct ever bind to any of the parallel regions
18505
      //  arising from the parallel construct.
18506
      // OpenMP [2.9.3.4, Restrictions, p.4]
18507
      //  A list item that appears in a reduction clause in worksharing
18508
      //  construct must not appear in a firstprivate clause in a task construct
18509
      //  encountered during execution of any of the worksharing regions arising
18510
      //  from the worksharing construct.
18511
9.89k
      if (isOpenMPTaskingDirective(CurrDir)) {
18512
2.25k
        DVar = DSAStack->hasInnermostDSA(
18513
2.25k
            D,
18514
2.25k
            [](OpenMPClauseKind C, bool AppliedToPointee) {
18515
1.62k
              return C == OMPC_reduction && 
!AppliedToPointee76
;
18516
1.62k
            },
18517
2.25k
            [](OpenMPDirectiveKind K) {
18518
1.69k
              return isOpenMPParallelDirective(K) ||
18519
1.69k
                     
isOpenMPWorksharingDirective(K)92
||
18520
1.69k
                     
isOpenMPTeamsDirective(K)68
;
18521
1.69k
            },
18522
2.25k
            /*FromParent=*/true);
18523
2.25k
        if (DVar.CKind == OMPC_reduction &&
18524
2.25k
            
(76
isOpenMPParallelDirective(DVar.DKind)76
||
18525
76
             
isOpenMPWorksharingDirective(DVar.DKind)18
||
18526
76
             
isOpenMPTeamsDirective(DVar.DKind)0
)) {
18527
76
          Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18528
76
              << getOpenMPDirectiveName(DVar.DKind);
18529
76
          reportOriginalDsa(*this, DSAStack, D, DVar);
18530
76
          continue;
18531
76
        }
18532
2.25k
      }
18533
18534
      // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18535
      // A list item cannot appear in both a map clause and a data-sharing
18536
      // attribute clause on the same construct
18537
      //
18538
      // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18539
      // A list item cannot appear in both a map clause and a data-sharing
18540
      // attribute clause on the same construct unless the construct is a
18541
      // combined construct.
18542
9.81k
      if ((LangOpts.OpenMP <= 45 &&
18543
9.81k
           
isOpenMPTargetExecutionDirective(CurrDir)1.00k
) ||
18544
9.81k
          
CurrDir == OMPD_target9.31k
) {
18545
1.17k
        OpenMPClauseKind ConflictKind;
18546
1.17k
        if (DSAStack->checkMappableExprComponentListsForDecl(
18547
1.17k
                VD, /*CurrentRegionOnly=*/true,
18548
1.17k
                [&ConflictKind](
18549
1.17k
                    OMPClauseMappableExprCommon::MappableExprComponentListRef,
18550
1.17k
                    OpenMPClauseKind WhereFoundClauseKind) {
18551
38
                  ConflictKind = WhereFoundClauseKind;
18552
38
                  return true;
18553
38
                })) {
18554
38
          Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18555
38
              << getOpenMPClauseName(OMPC_firstprivate)
18556
38
              << getOpenMPClauseName(ConflictKind)
18557
38
              << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18558
38
          reportOriginalDsa(*this, DSAStack, D, DVar);
18559
38
          continue;
18560
38
        }
18561
1.17k
      }
18562
9.81k
    }
18563
18564
    // Variably modified types are not supported for tasks.
18565
80.0k
    if (!Type->isAnyPointerType() && 
Type->isVariablyModifiedType()63.7k
&&
18566
80.0k
        
isOpenMPTaskingDirective(80
DSAStack80
->getCurrentDirective())) {
18567
0
      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18568
0
          << getOpenMPClauseName(OMPC_firstprivate) << Type
18569
0
          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18570
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18571
0
                               VarDecl::DeclarationOnly;
18572
0
      Diag(D->getLocation(),
18573
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18574
0
          << D;
18575
0
      continue;
18576
0
    }
18577
18578
80.0k
    Type = Type.getUnqualifiedType();
18579
80.0k
    VarDecl *VDPrivate =
18580
80.0k
        buildVarDecl(*this, ELoc, Type, D->getName(),
18581
80.0k
                     D->hasAttrs() ? 
&D->getAttrs()232
:
nullptr79.7k
,
18582
80.0k
                     VD ? 
cast<DeclRefExpr>(SimpleRefExpr)79.6k
:
nullptr402
);
18583
    // Generate helper private variable and initialize it with the value of the
18584
    // original variable. The address of the original variable is replaced by
18585
    // the address of the new private variable in the CodeGen. This new variable
18586
    // is not added to IdResolver, so the code in the OpenMP region uses
18587
    // original variable for proper diagnostics and variable capturing.
18588
80.0k
    Expr *VDInitRefExpr = nullptr;
18589
    // For arrays generate initializer for single element and replace it by the
18590
    // original array element in CodeGen.
18591
80.0k
    if (Type->isArrayType()) {
18592
1.45k
      VarDecl *VDInit =
18593
1.45k
          buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
18594
1.45k
      VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
18595
1.45k
      Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
18596
1.45k
      ElemType = ElemType.getUnqualifiedType();
18597
1.45k
      VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
18598
1.45k
                                         ".firstprivate.temp");
18599
1.45k
      InitializedEntity Entity =
18600
1.45k
          InitializedEntity::InitializeVariable(VDInitTemp);
18601
1.45k
      InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
18602
18603
1.45k
      InitializationSequence InitSeq(*this, Entity, Kind, Init);
18604
1.45k
      ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
18605
1.45k
      if (Result.isInvalid())
18606
48
        VDPrivate->setInvalidDecl();
18607
1.40k
      else
18608
1.40k
        VDPrivate->setInit(Result.getAs<Expr>());
18609
      // Remove temp variable declaration.
18610
1.45k
      Context.Deallocate(VDInitTemp);
18611
78.5k
    } else {
18612
78.5k
      VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
18613
78.5k
                                     ".firstprivate.temp");
18614
78.5k
      VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
18615
78.5k
                                       RefExpr->getExprLoc());
18616
78.5k
      AddInitializerToDecl(VDPrivate,
18617
78.5k
                           DefaultLvalueConversion(VDInitRefExpr).get(),
18618
78.5k
                           /*DirectInit=*/false);
18619
78.5k
    }
18620
80.0k
    if (VDPrivate->isInvalidDecl()) {
18621
48
      if (IsImplicitClause) {
18622
0
        Diag(RefExpr->getExprLoc(),
18623
0
             diag::note_omp_task_predetermined_firstprivate_here);
18624
0
      }
18625
48
      continue;
18626
48
    }
18627
79.9k
    CurContext->addDecl(VDPrivate);
18628
79.9k
    DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18629
79.9k
        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
18630
79.9k
        RefExpr->getExprLoc());
18631
79.9k
    DeclRefExpr *Ref = nullptr;
18632
79.9k
    if (!VD && 
!CurContext->isDependentContext()402
) {
18633
402
      if (TopDVar.CKind == OMPC_lastprivate) {
18634
0
        Ref = TopDVar.PrivateCopy;
18635
402
      } else {
18636
402
        auto *FD = dyn_cast<FieldDecl>(D);
18637
402
        VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : 
nullptr0
;
18638
402
        if (VD)
18639
10
          Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18640
10
                                 RefExpr->getExprLoc());
18641
392
        else
18642
392
          Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18643
402
        if (VD || 
!isOpenMPCapturedDecl(D)392
)
18644
346
          ExprCaptures.push_back(Ref->getDecl());
18645
402
      }
18646
402
    }
18647
79.9k
    if (!IsImplicitClause)
18648
9.72k
      DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18649
79.9k
    Vars.push_back((VD || 
CurContext->isDependentContext()402
)
18650
79.9k
                       ? 
RefExpr->IgnoreParens()79.5k
18651
79.9k
                       : 
Ref402
);
18652
79.9k
    PrivateCopies.push_back(VDPrivateRefExpr);
18653
79.9k
    Inits.push_back(VDInitRefExpr);
18654
79.9k
  }
18655
18656
66.0k
  if (Vars.empty())
18657
1.05k
    return nullptr;
18658
18659
64.9k
  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18660
64.9k
                                       Vars, PrivateCopies, Inits,
18661
64.9k
                                       buildPreInits(Context, ExprCaptures));
18662
66.0k
}
18663
18664
OMPClause *Sema::ActOnOpenMPLastprivateClause(
18665
    ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
18666
    SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
18667
8.78k
    SourceLocation LParenLoc, SourceLocation EndLoc) {
18668
8.78k
  if (LPKind == OMPC_LASTPRIVATE_unknown && 
LPKindLoc.isValid()8.66k
) {
18669
20
    assert(ColonLoc.isValid() && "Colon location must be valid.");
18670
20
    Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18671
20
        << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
18672
20
                                   /*Last=*/OMPC_LASTPRIVATE_unknown)
18673
20
        << getOpenMPClauseName(OMPC_lastprivate);
18674
20
    return nullptr;
18675
20
  }
18676
18677
8.76k
  SmallVector<Expr *, 8> Vars;
18678
8.76k
  SmallVector<Expr *, 8> SrcExprs;
18679
8.76k
  SmallVector<Expr *, 8> DstExprs;
18680
8.76k
  SmallVector<Expr *, 8> AssignmentOps;
18681
8.76k
  SmallVector<Decl *, 4> ExprCaptures;
18682
8.76k
  SmallVector<Expr *, 4> ExprPostUpdates;
18683
14.4k
  for (Expr *RefExpr : VarList) {
18684
14.4k
    assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18685
14.4k
    SourceLocation ELoc;
18686
14.4k
    SourceRange ERange;
18687
14.4k
    Expr *SimpleRefExpr = RefExpr;
18688
14.4k
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18689
14.4k
    if (Res.second) {
18690
      // It will be analyzed later.
18691
2.39k
      Vars.push_back(RefExpr);
18692
2.39k
      SrcExprs.push_back(nullptr);
18693
2.39k
      DstExprs.push_back(nullptr);
18694
2.39k
      AssignmentOps.push_back(nullptr);
18695
2.39k
    }
18696
14.4k
    ValueDecl *D = Res.first;
18697
14.4k
    if (!D)
18698
3.13k
      continue;
18699
18700
11.2k
    QualType Type = D->getType();
18701
11.2k
    auto *VD = dyn_cast<VarDecl>(D);
18702
18703
    // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
18704
    //  A variable that appears in a lastprivate clause must not have an
18705
    //  incomplete type or a reference type.
18706
11.2k
    if (RequireCompleteType(ELoc, Type,
18707
11.2k
                            diag::err_omp_lastprivate_incomplete_type))
18708
252
      continue;
18709
11.0k
    Type = Type.getNonReferenceType();
18710
18711
    // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18712
    // A variable that is privatized must not have a const-qualified type
18713
    // unless it is of class type with a mutable member. This restriction does
18714
    // not apply to the firstprivate clause.
18715
    //
18716
    // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
18717
    // A variable that appears in a lastprivate clause must not have a
18718
    // const-qualified type unless it is of class type with a mutable member.
18719
11.0k
    if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
18720
756
      continue;
18721
18722
    // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
18723
    // A list item that appears in a lastprivate clause with the conditional
18724
    // modifier must be a scalar variable.
18725
10.2k
    if (LPKind == OMPC_LASTPRIVATE_conditional && 
!Type->isScalarType()214
) {
18726
18
      Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18727
18
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18728
18
                               VarDecl::DeclarationOnly;
18729
18
      Diag(D->getLocation(),
18730
18
           IsDecl ? 
diag::note_previous_decl0
: diag::note_defined_here)
18731
18
          << D;
18732
18
      continue;
18733
18
    }
18734
18735
10.2k
    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18736
    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18737
    // in a Construct]
18738
    //  Variables with the predetermined data-sharing attributes may not be
18739
    //  listed in data-sharing attributes clauses, except for the cases
18740
    //  listed below.
18741
    // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18742
    // A list item may appear in a firstprivate or lastprivate clause but not
18743
    // both.
18744
10.2k
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18745
10.2k
    if (DVar.CKind != OMPC_unknown && 
DVar.CKind != OMPC_lastprivate1.58k
&&
18746
10.2k
        
(1.02k
isOpenMPDistributeDirective(CurrDir)1.02k
||
18747
1.02k
         
DVar.CKind != OMPC_firstprivate746
) &&
18748
10.2k
        
(696
DVar.CKind != OMPC_private696
||
DVar.RefExpr != nullptr126
)) {
18749
696
      Diag(ELoc, diag::err_omp_wrong_dsa)
18750
696
          << getOpenMPClauseName(DVar.CKind)
18751
696
          << getOpenMPClauseName(OMPC_lastprivate);
18752
696
      reportOriginalDsa(*this, DSAStack, D, DVar);
18753
696
      continue;
18754
696
    }
18755
18756
    // OpenMP [2.14.3.5, Restrictions, p.2]
18757
    // A list item that is private within a parallel region, or that appears in
18758
    // the reduction clause of a parallel construct, must not appear in a
18759
    // lastprivate clause on a worksharing construct if any of the corresponding
18760
    // worksharing regions ever binds to any of the corresponding parallel
18761
    // regions.
18762
9.55k
    DSAStackTy::DSAVarData TopDVar = DVar;
18763
9.55k
    if (isOpenMPWorksharingDirective(CurrDir) &&
18764
9.55k
        
!isOpenMPParallelDirective(CurrDir)4.66k
&&
18765
9.55k
        
!isOpenMPTeamsDirective(CurrDir)1.26k
) {
18766
1.25k
      DVar = DSAStack->getImplicitDSA(D, true);
18767
1.25k
      if (DVar.CKind != OMPC_shared) {
18768
36
        Diag(ELoc, diag::err_omp_required_access)
18769
36
            << getOpenMPClauseName(OMPC_lastprivate)
18770
36
            << getOpenMPClauseName(OMPC_shared);
18771
36
        reportOriginalDsa(*this, DSAStack, D, DVar);
18772
36
        continue;
18773
36
      }
18774
1.25k
    }
18775
18776
    // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
18777
    //  A variable of class type (or array thereof) that appears in a
18778
    //  lastprivate clause requires an accessible, unambiguous default
18779
    //  constructor for the class type, unless the list item is also specified
18780
    //  in a firstprivate clause.
18781
    //  A variable of class type (or array thereof) that appears in a
18782
    //  lastprivate clause requires an accessible, unambiguous copy assignment
18783
    //  operator for the class type.
18784
9.52k
    Type = Context.getBaseElementType(Type).getNonReferenceType();
18785
9.52k
    VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
18786
9.52k
                                  Type.getUnqualifiedType(), ".lastprivate.src",
18787
9.52k
                                  D->hasAttrs() ? 
&D->getAttrs()64
:
nullptr9.45k
);
18788
9.52k
    DeclRefExpr *PseudoSrcExpr =
18789
9.52k
        buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
18790
9.52k
    VarDecl *DstVD =
18791
9.52k
        buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
18792
9.52k
                     D->hasAttrs() ? 
&D->getAttrs()64
:
nullptr9.45k
);
18793
9.52k
    DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18794
    // For arrays generate assignment operation for single element and replace
18795
    // it by the original array element in CodeGen.
18796
9.52k
    ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
18797
9.52k
                                         PseudoDstExpr, PseudoSrcExpr);
18798
9.52k
    if (AssignmentOp.isInvalid())
18799
0
      continue;
18800
9.52k
    AssignmentOp =
18801
9.52k
        ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18802
9.52k
    if (AssignmentOp.isInvalid())
18803
0
      continue;
18804
18805
9.52k
    DeclRefExpr *Ref = nullptr;
18806
9.52k
    if (!VD && 
!CurContext->isDependentContext()204
) {
18807
204
      if (TopDVar.CKind == OMPC_firstprivate) {
18808
16
        Ref = TopDVar.PrivateCopy;
18809
188
      } else {
18810
188
        Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18811
188
        if (!isOpenMPCapturedDecl(D))
18812
164
          ExprCaptures.push_back(Ref->getDecl());
18813
188
      }
18814
204
      if ((TopDVar.CKind == OMPC_firstprivate && 
!TopDVar.PrivateCopy16
) ||
18815
204
          (!isOpenMPCapturedDecl(D) &&
18816
204
           
Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()180
)) {
18817
20
        ExprResult RefRes = DefaultLvalueConversion(Ref);
18818
20
        if (!RefRes.isUsable())
18819
0
          continue;
18820
20
        ExprResult PostUpdateRes =
18821
20
            BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18822
20
                       RefRes.get());
18823
20
        if (!PostUpdateRes.isUsable())
18824
0
          continue;
18825
20
        ExprPostUpdates.push_back(
18826
20
            IgnoredValueConversions(PostUpdateRes.get()).get());
18827
20
      }
18828
204
    }
18829
9.52k
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18830
9.52k
    Vars.push_back((VD || 
CurContext->isDependentContext()204
)
18831
9.52k
                       ? 
RefExpr->IgnoreParens()9.31k
18832
9.52k
                       : 
Ref204
);
18833
9.52k
    SrcExprs.push_back(PseudoSrcExpr);
18834
9.52k
    DstExprs.push_back(PseudoDstExpr);
18835
9.52k
    AssignmentOps.push_back(AssignmentOp.get());
18836
9.52k
  }
18837
18838
8.76k
  if (Vars.empty())
18839
1.81k
    return nullptr;
18840
18841
6.95k
  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18842
6.95k
                                      Vars, SrcExprs, DstExprs, AssignmentOps,
18843
6.95k
                                      LPKind, LPKindLoc, ColonLoc,
18844
6.95k
                                      buildPreInits(Context, ExprCaptures),
18845
6.95k
                                      buildPostUpdate(*this, ExprPostUpdates));
18846
8.76k
}
18847
18848
OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
18849
                                         SourceLocation StartLoc,
18850
                                         SourceLocation LParenLoc,
18851
7.24k
                                         SourceLocation EndLoc) {
18852
7.24k
  SmallVector<Expr *, 8> Vars;
18853
7.72k
  for (Expr *RefExpr : VarList) {
18854
7.72k
    assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18855
7.72k
    SourceLocation ELoc;
18856
7.72k
    SourceRange ERange;
18857
7.72k
    Expr *SimpleRefExpr = RefExpr;
18858
7.72k
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18859
7.72k
    if (Res.second) {
18860
      // It will be analyzed later.
18861
1.43k
      Vars.push_back(RefExpr);
18862
1.43k
    }
18863
7.72k
    ValueDecl *D = Res.first;
18864
7.72k
    if (!D)
18865
1.51k
      continue;
18866
18867
6.21k
    auto *VD = dyn_cast<VarDecl>(D);
18868
    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18869
    // in a Construct]
18870
    //  Variables with the predetermined data-sharing attributes may not be
18871
    //  listed in data-sharing attributes clauses, except for the cases
18872
    //  listed below. For these exceptions only, listing a predetermined
18873
    //  variable in a data-sharing attribute clause is allowed and overrides
18874
    //  the variable's predetermined data-sharing attributes.
18875
6.21k
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18876
6.21k
    if (DVar.CKind != OMPC_unknown && 
DVar.CKind != OMPC_shared232
&&
18877
6.21k
        
DVar.RefExpr168
) {
18878
168
      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18879
168
                                          << getOpenMPClauseName(OMPC_shared);
18880
168
      reportOriginalDsa(*this, DSAStack, D, DVar);
18881
168
      continue;
18882
168
    }
18883
18884
6.04k
    DeclRefExpr *Ref = nullptr;
18885
6.04k
    if (!VD && 
isOpenMPCapturedDecl(D)140
&&
!CurContext->isDependentContext()0
)
18886
0
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18887
6.04k
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18888
6.04k
    Vars.push_back((VD || 
!Ref140
||
CurContext->isDependentContext()0
)
18889
6.04k
                       ? RefExpr->IgnoreParens()
18890
6.04k
                       : 
Ref0
);
18891
6.04k
  }
18892
18893
7.24k
  if (Vars.empty())
18894
203
    return nullptr;
18895
18896
7.03k
  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18897
7.24k
}
18898
18899
namespace {
18900
class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
18901
  DSAStackTy *Stack;
18902
18903
public:
18904
24.1k
  bool VisitDeclRefExpr(DeclRefExpr *E) {
18905
24.1k
    if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
18906
24.1k
      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
18907
24.1k
      if (DVar.CKind == OMPC_shared && 
!DVar.RefExpr0
)
18908
0
        return false;
18909
24.1k
      if (DVar.CKind != OMPC_unknown)
18910
5.33k
        return true;
18911
18.7k
      DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
18912
18.7k
          VD,
18913
18.7k
          [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
18914
9.30k
            return isOpenMPPrivate(C) && 
!AppliedToPointee7.18k
;
18915
9.30k
          },
18916
18.7k
          [](OpenMPDirectiveKind) 
{ return true; }13.7k
,
18917
18.7k
          /*FromParent=*/true);
18918
18.7k
      return DVarPrivate.CKind != OMPC_unknown;
18919
24.1k
    }
18920
0
    return false;
18921
24.1k
  }
18922
10.8k
  bool VisitStmt(Stmt *S) {
18923
13.5k
    for (Stmt *Child : S->children()) {
18924
13.5k
      if (Child && Visit(Child))
18925
8.00k
        return true;
18926
13.5k
    }
18927
2.88k
    return false;
18928
10.8k
  }
18929
21.4k
  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
18930
};
18931
} // namespace
18932
18933
namespace {
18934
// Transform MemberExpression for specified FieldDecl of current class to
18935
// DeclRefExpr to specified OMPCapturedExprDecl.
18936
class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
18937
  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
18938
  ValueDecl *Field = nullptr;
18939
  DeclRefExpr *CapturedExpr = nullptr;
18940
18941
public:
18942
  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
18943
60
      : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
18944
18945
140
  ExprResult TransformMemberExpr(MemberExpr *E) {
18946
140
    if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
18947
140
        
E->getMemberDecl() == Field100
) {
18948
60
      CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
18949
60
      return CapturedExpr;
18950
60
    }
18951
80
    return BaseTransform::TransformMemberExpr(E);
18952
140
  }
18953
60
  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
18954
};
18955
} // namespace
18956
18957
template <typename T, typename U>
18958
static T filterLookupForUDReductionAndMapper(
18959
384k
    SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
18960
384k
  for (U &Set : Lookups) {
18961
223k
    for (auto *D : Set) {
18962
2.94k
      if (T Res = Gen(cast<ValueDecl>(D)))
18963
879
        return Res;
18964
2.94k
    }
18965
223k
  }
18966
383k
  return T();
18967
384k
}
SemaOpenMP.cpp:bool filterLookupForUDReductionAndMapper<bool, clang::UnresolvedSet<8u> >(llvm::SmallVectorImpl<clang::UnresolvedSet<8u> >&, llvm::function_ref<bool (clang::ValueDecl*)>)
Line
Count
Source
18959
128k
    SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
18960
128k
  for (U &Set : Lookups) {
18961
58.2k
    for (auto *D : Set) {
18962
1.40k
      if (T Res = Gen(cast<ValueDecl>(D)))
18963
0
        return Res;
18964
1.40k
    }
18965
58.2k
  }
18966
128k
  return T();
18967
128k
}
SemaOpenMP.cpp:clang::ValueDecl* filterLookupForUDReductionAndMapper<clang::ValueDecl*, clang::UnresolvedSet<8u> >(llvm::SmallVectorImpl<clang::UnresolvedSet<8u> >&, llvm::function_ref<clang::ValueDecl* (clang::ValueDecl*)>)
Line
Count
Source
18959
256k
    SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
18960
256k
  for (U &Set : Lookups) {
18961
165k
    for (auto *D : Set) {
18962
1.54k
      if (T Res = Gen(cast<ValueDecl>(D)))
18963
879
        return Res;
18964
1.54k
    }
18965
165k
  }
18966
255k
  return T();
18967
256k
}
18968
18969
0
static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
18970
0
  assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
18971
18972
0
  for (auto *RD : D->redecls()) {
18973
    // Don't bother with extra checks if we already know this one isn't visible.
18974
0
    if (RD == D)
18975
0
      continue;
18976
18977
0
    auto ND = cast<NamedDecl>(RD);
18978
0
    if (LookupResult::isVisible(SemaRef, ND))
18979
0
      return ND;
18980
0
  }
18981
18982
0
  return nullptr;
18983
0
}
18984
18985
static void
18986
argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
18987
                        SourceLocation Loc, QualType Ty,
18988
127k
                        SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
18989
  // Find all of the associated namespaces and classes based on the
18990
  // arguments we have.
18991
127k
  Sema::AssociatedNamespaceSet AssociatedNamespaces;
18992
127k
  Sema::AssociatedClassSet AssociatedClasses;
18993
127k
  OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
18994
127k
  SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
18995
127k
                                             AssociatedClasses);
18996
18997
  // C++ [basic.lookup.argdep]p3:
18998
  //   Let X be the lookup set produced by unqualified lookup (3.4.1)
18999
  //   and let Y be the lookup set produced by argument dependent
19000
  //   lookup (defined as follows). If X contains [...] then Y is
19001
  //   empty. Otherwise Y is the set of declarations found in the
19002
  //   namespaces associated with the argument types as described
19003
  //   below. The set of declarations found by the lookup of the name
19004
  //   is the union of X and Y.
19005
  //
19006
  // Here, we compute Y and add its members to the overloaded
19007
  // candidate set.
19008
127k
  for (auto *NS : AssociatedNamespaces) {
19009
    //   When considering an associated namespace, the lookup is the
19010
    //   same as the lookup performed when the associated namespace is
19011
    //   used as a qualifier (3.4.3.2) except that:
19012
    //
19013
    //     -- Any using-directives in the associated namespace are
19014
    //        ignored.
19015
    //
19016
    //     -- Any namespace-scope friend functions declared in
19017
    //        associated classes are visible within their respective
19018
    //        namespaces even if they are not visible during an ordinary
19019
    //        lookup (11.4).
19020
42.5k
    DeclContext::lookup_result R = NS->lookup(Id.getName());
19021
42.5k
    for (auto *D : R) {
19022
16.9k
      auto *Underlying = D;
19023
16.9k
      if (auto *USD = dyn_cast<UsingShadowDecl>(D))
19024
0
        Underlying = USD->getTargetDecl();
19025
19026
16.9k
      if (!isa<OMPDeclareReductionDecl>(Underlying) &&
19027
16.9k
          
!isa<OMPDeclareMapperDecl>(Underlying)16.8k
)
19028
16.5k
        continue;
19029
19030
368
      if (!SemaRef.isVisible(D)) {
19031
0
        D = findAcceptableDecl(SemaRef, D);
19032
0
        if (!D)
19033
0
          continue;
19034
0
        if (auto *USD = dyn_cast<UsingShadowDecl>(D))
19035
0
          Underlying = USD->getTargetDecl();
19036
0
      }
19037
368
      Lookups.emplace_back();
19038
368
      Lookups.back().addDecl(Underlying);
19039
368
    }
19040
42.5k
  }
19041
127k
}
19042
19043
static ExprResult
19044
buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
19045
                         Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
19046
                         const DeclarationNameInfo &ReductionId, QualType Ty,
19047
97.3k
                         CXXCastPath &BasePath, Expr *UnresolvedReduction) {
19048
97.3k
  if (ReductionIdScopeSpec.isInvalid())
19049
0
    return ExprError();
19050
97.3k
  SmallVector<UnresolvedSet<8>, 4> Lookups;
19051
97.3k
  if (S) {
19052
57.2k
    LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
19053
57.2k
    Lookup.suppressDiagnostics();
19054
57.8k
    while (S && 
SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)57.3k
) {
19055
508
      NamedDecl *D = Lookup.getRepresentativeDecl();
19056
1.07k
      do {
19057
1.07k
        S = S->getParent();
19058
1.07k
      } while (S && 
!S->isDeclScope(D)1.03k
);
19059
508
      if (S)
19060
468
        S = S->getParent();
19061
508
      Lookups.emplace_back();
19062
508
      Lookups.back().append(Lookup.begin(), Lookup.end());
19063
508
      Lookup.clear();
19064
508
    }
19065
57.2k
  } else 
if (auto *40.0k
ULE40.0k
=
19066
40.0k
                 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
19067
40.0k
    Lookups.push_back(UnresolvedSet<8>());
19068
40.0k
    Decl *PrevD = nullptr;
19069
40.0k
    for (NamedDecl *D : ULE->decls()) {
19070
210
      if (D == PrevD)
19071
84
        Lookups.push_back(UnresolvedSet<8>());
19072
126
      else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
19073
126
        Lookups.back().addDecl(DRD);
19074
210
      PrevD = D;
19075
210
    }
19076
40.0k
  }
19077
97.3k
  if (SemaRef.CurContext->isDependentContext() || 
Ty->isDependentType()67.3k
||
19078
97.3k
      
Ty->isInstantiationDependentType()67.3k
||
19079
97.3k
      
Ty->containsUnexpandedParameterPack()67.3k
||
19080
97.3k
      
filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) 67.3k
{
19081
612
        return !D->isInvalidDecl() &&
19082
612
               
(600
D->getType()->isDependentType()600
||
19083
600
                D->getType()->isInstantiationDependentType() ||
19084
600
                D->getType()->containsUnexpandedParameterPack());
19085
30.0k
      })) {
19086
30.0k
    UnresolvedSet<8> ResSet;
19087
30.0k
    for (const UnresolvedSet<8> &Set : Lookups) {
19088
90
      if (Set.empty())
19089
0
        continue;
19090
90
      ResSet.append(Set.begin(), Set.end());
19091
      // The last item marks the end of all declarations at the specified scope.
19092
90
      ResSet.addDecl(Set[Set.size() - 1]);
19093
90
    }
19094
30.0k
    return UnresolvedLookupExpr::Create(
19095
30.0k
        SemaRef.Context, /*NamingClass=*/nullptr,
19096
30.0k
        ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
19097
30.0k
        /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
19098
30.0k
  }
19099
  // Lookup inside the classes.
19100
  // C++ [over.match.oper]p3:
19101
  //   For a unary operator @ with an operand of a type whose
19102
  //   cv-unqualified version is T1, and for a binary operator @ with
19103
  //   a left operand of a type whose cv-unqualified version is T1 and
19104
  //   a right operand of a type whose cv-unqualified version is T2,
19105
  //   three sets of candidate functions, designated member
19106
  //   candidates, non-member candidates and built-in candidates, are
19107
  //   constructed as follows:
19108
  //     -- If T1 is a complete class type or a class currently being
19109
  //        defined, the set of member candidates is the result of the
19110
  //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
19111
  //        the set of member candidates is empty.
19112
67.3k
  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
19113
67.3k
  Lookup.suppressDiagnostics();
19114
67.3k
  if (const auto *TyRec = Ty->getAs<RecordType>()) {
19115
    // Complete the type if it can be completed.
19116
    // If the type is neither complete nor being defined, bail out now.
19117
25.1k
    if (SemaRef.isCompleteType(Loc, Ty) || 
TyRec->isBeingDefined()0
||
19118
25.1k
        
TyRec->getDecl()->getDefinition()0
) {
19119
25.1k
      Lookup.clear();
19120
25.1k
      SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
19121
25.1k
      if (Lookup.empty()) {
19122
25.1k
        Lookups.emplace_back();
19123
25.1k
        Lookups.back().append(Lookup.begin(), Lookup.end());
19124
25.1k
      }
19125
25.1k
    }
19126
25.1k
  }
19127
  // Perform ADL.
19128
67.3k
  if (SemaRef.getLangOpts().CPlusPlus)
19129
67.0k
    argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
19130
67.3k
  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19131
67.3k
          Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
19132
545
            if (!D->isInvalidDecl() &&
19133
545
                
SemaRef.Context.hasSameType(D->getType(), Ty)533
)
19134
376
              return D;
19135
169
            return nullptr;
19136
545
          }))
19137
376
    return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
19138
376
                                    VK_LValue, Loc);
19139
66.9k
  if (SemaRef.getLangOpts().CPlusPlus) {
19140
66.7k
    if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19141
66.7k
            Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
19142
80
              if (!D->isInvalidDecl() &&
19143
80
                  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
19144
80
                  
!Ty.isMoreQualifiedThan(D->getType())36
)
19145
36
                return D;
19146
44
              return nullptr;
19147
80
            })) {
19148
36
      CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
19149
36
                         /*DetectVirtual=*/false);
19150
36
      if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
19151
36
        if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
19152
36
                VD->getType().getUnqualifiedType()))) {
19153
36
          if (SemaRef.CheckBaseClassAccess(
19154
36
                  Loc, VD->getType(), Ty, Paths.front(),
19155
36
                  /*DiagID=*/0) != Sema::AR_inaccessible) {
19156
36
            SemaRef.BuildBasePathArray(Paths, BasePath);
19157
36
            return SemaRef.BuildDeclRefExpr(
19158
36
                VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
19159
36
          }
19160
36
        }
19161
36
      }
19162
36
    }
19163
66.7k
  }
19164
66.9k
  if (ReductionIdScopeSpec.isSet()) {
19165
2
    SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
19166
2
        << Ty << Range;
19167
2
    return ExprError();
19168
2
  }
19169
66.8k
  return ExprEmpty();
19170
66.9k
}
19171
19172
namespace {
19173
/// Data for the reduction-based clauses.
19174
struct ReductionData {
19175
  /// List of original reduction items.
19176
  SmallVector<Expr *, 8> Vars;
19177
  /// List of private copies of the reduction items.
19178
  SmallVector<Expr *, 8> Privates;
19179
  /// LHS expressions for the reduction_op expressions.
19180
  SmallVector<Expr *, 8> LHSs;
19181
  /// RHS expressions for the reduction_op expressions.
19182
  SmallVector<Expr *, 8> RHSs;
19183
  /// Reduction operation expression.
19184
  SmallVector<Expr *, 8> ReductionOps;
19185
  /// inscan copy operation expressions.
19186
  SmallVector<Expr *, 8> InscanCopyOps;
19187
  /// inscan copy temp array expressions for prefix sums.
19188
  SmallVector<Expr *, 8> InscanCopyArrayTemps;
19189
  /// inscan copy temp array element expressions for prefix sums.
19190
  SmallVector<Expr *, 8> InscanCopyArrayElems;
19191
  /// Taskgroup descriptors for the corresponding reduction items in
19192
  /// in_reduction clauses.
19193
  SmallVector<Expr *, 8> TaskgroupDescriptors;
19194
  /// List of captures for clause.
19195
  SmallVector<Decl *, 4> ExprCaptures;
19196
  /// List of postupdate expressions.
19197
  SmallVector<Expr *, 4> ExprPostUpdates;
19198
  /// Reduction modifier.
19199
  unsigned RedModifier = 0;
19200
  ReductionData() = delete;
19201
  /// Reserves required memory for the reduction data.
19202
116k
  ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
19203
116k
    Vars.reserve(Size);
19204
116k
    Privates.reserve(Size);
19205
116k
    LHSs.reserve(Size);
19206
116k
    RHSs.reserve(Size);
19207
116k
    ReductionOps.reserve(Size);
19208
116k
    if (RedModifier == OMPC_REDUCTION_inscan) {
19209
213
      InscanCopyOps.reserve(Size);
19210
213
      InscanCopyArrayTemps.reserve(Size);
19211
213
      InscanCopyArrayElems.reserve(Size);
19212
213
    }
19213
116k
    TaskgroupDescriptors.reserve(Size);
19214
116k
    ExprCaptures.reserve(Size);
19215
116k
    ExprPostUpdates.reserve(Size);
19216
116k
  }
19217
  /// Stores reduction item and reduction operation only (required for dependent
19218
  /// reduction item).
19219
30.0k
  void push(Expr *Item, Expr *ReductionOp) {
19220
30.0k
    Vars.emplace_back(Item);
19221
30.0k
    Privates.emplace_back(nullptr);
19222
30.0k
    LHSs.emplace_back(nullptr);
19223
30.0k
    RHSs.emplace_back(nullptr);
19224
30.0k
    ReductionOps.emplace_back(ReductionOp);
19225
30.0k
    TaskgroupDescriptors.emplace_back(nullptr);
19226
30.0k
    if (RedModifier == OMPC_REDUCTION_inscan) {
19227
22
      InscanCopyOps.push_back(nullptr);
19228
22
      InscanCopyArrayTemps.push_back(nullptr);
19229
22
      InscanCopyArrayElems.push_back(nullptr);
19230
22
    }
19231
30.0k
  }
19232
  /// Stores reduction data.
19233
  void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
19234
            Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
19235
48.6k
            Expr *CopyArrayElem) {
19236
48.6k
    Vars.emplace_back(Item);
19237
48.6k
    Privates.emplace_back(Private);
19238
48.6k
    LHSs.emplace_back(LHS);
19239
48.6k
    RHSs.emplace_back(RHS);
19240
48.6k
    ReductionOps.emplace_back(ReductionOp);
19241
48.6k
    TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
19242
48.6k
    if (RedModifier == OMPC_REDUCTION_inscan) {
19243
311
      InscanCopyOps.push_back(CopyOp);
19244
311
      InscanCopyArrayTemps.push_back(CopyArrayTemp);
19245
311
      InscanCopyArrayElems.push_back(CopyArrayElem);
19246
48.3k
    } else {
19247
48.3k
      assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
19248
48.3k
             CopyArrayElem == nullptr &&
19249
48.3k
             "Copy operation must be used for inscan reductions only.");
19250
48.3k
    }
19251
48.6k
  }
19252
};
19253
} // namespace
19254
19255
static bool checkOMPArraySectionConstantForReduction(
19256
    ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
19257
690
    SmallVectorImpl<llvm::APSInt> &ArraySizes) {
19258
690
  const Expr *Length = OASE->getLength();
19259
690
  if (Length == nullptr) {
19260
    // For array sections of the form [1:] or [:], we would need to analyze
19261
    // the lower bound...
19262
57
    if (OASE->getColonLocFirst().isValid())
19263
52
      return false;
19264
19265
    // This is an array subscript which has implicit length 1!
19266
5
    SingleElement = true;
19267
5
    ArraySizes.push_back(llvm::APSInt::get(1));
19268
633
  } else {
19269
633
    Expr::EvalResult Result;
19270
633
    if (!Length->EvaluateAsInt(Result, Context))
19271
360
      return false;
19272
19273
273
    llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19274
273
    SingleElement = (ConstantLengthValue.getSExtValue() == 1);
19275
273
    ArraySizes.push_back(ConstantLengthValue);
19276
273
  }
19277
19278
  // Get the base of this array section and walk up from there.
19279
278
  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
19280
19281
  // We require length = 1 for all array sections except the right-most to
19282
  // guarantee that the memory region is contiguous and has no holes in it.
19283
318
  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
19284
177
    Length = TempOASE->getLength();
19285
177
    if (Length == nullptr) {
19286
      // For array sections of the form [1:] or [:], we would need to analyze
19287
      // the lower bound...
19288
0
      if (OASE->getColonLocFirst().isValid())
19289
0
        return false;
19290
19291
      // This is an array subscript which has implicit length 1!
19292
0
      ArraySizes.push_back(llvm::APSInt::get(1));
19293
177
    } else {
19294
177
      Expr::EvalResult Result;
19295
177
      if (!Length->EvaluateAsInt(Result, Context))
19296
24
        return false;
19297
19298
153
      llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19299
153
      if (ConstantLengthValue.getSExtValue() != 1)
19300
113
        return false;
19301
19302
40
      ArraySizes.push_back(ConstantLengthValue);
19303
40
    }
19304
40
    Base = TempOASE->getBase()->IgnoreParenImpCasts();
19305
40
  }
19306
19307
  // If we have a single element, we don't need to add the implicit lengths.
19308
141
  if (!SingleElement) {
19309
131
    while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
19310
      // Has implicit length 1!
19311
8
      ArraySizes.push_back(llvm::APSInt::get(1));
19312
8
      Base = TempASE->getBase()->IgnoreParenImpCasts();
19313
8
    }
19314
123
  }
19315
19316
  // This array section can be privatized as a single value or as a constant
19317
  // sized array.
19318
141
  return true;
19319
278
}
19320
19321
static BinaryOperatorKind
19322
57.4k
getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
19323
57.4k
  if (BOK == BO_Add)
19324
34.5k
    return BO_AddAssign;
19325
22.9k
  if (BOK == BO_Mul)
19326
2.37k
    return BO_MulAssign;
19327
20.5k
  if (BOK == BO_And)
19328
4.46k
    return BO_AndAssign;
19329
16.0k
  if (BOK == BO_Or)
19330
3.55k
    return BO_OrAssign;
19331
12.5k
  if (BOK == BO_Xor)
19332
3.70k
    return BO_XorAssign;
19333
8.80k
  return BOK;
19334
12.5k
}
19335
19336
static bool actOnOMPReductionKindClause(
19337
    Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
19338
    ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19339
    SourceLocation ColonLoc, SourceLocation EndLoc,
19340
    CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19341
116k
    ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
19342
116k
  DeclarationName DN = ReductionId.getName();
19343
116k
  OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
19344
116k
  BinaryOperatorKind BOK = BO_Comma;
19345
19346
116k
  ASTContext &Context = S.Context;
19347
  // OpenMP [2.14.3.6, reduction clause]
19348
  // C
19349
  // reduction-identifier is either an identifier or one of the following
19350
  // operators: +, -, *,  &, |, ^, && and ||
19351
  // C++
19352
  // reduction-identifier is either an id-expression or one of the following
19353
  // operators: +, -, *, &, |, ^, && and ||
19354
116k
  switch (OOK) {
19355
58.9k
  case OO_Plus:
19356
58.9k
    BOK = BO_Add;
19357
58.9k
    break;
19358
5.30k
  case OO_Minus:
19359
    // Minus(-) operator is not supported in TR11 (OpenMP 6.0). Setting BOK to
19360
    // BO_Comma will automatically diagnose it for OpenMP > 52 as not allowed
19361
    // reduction identifier.
19362
5.30k
    if (S.LangOpts.OpenMP > 52)
19363
1.35k
      BOK = BO_Comma;
19364
3.95k
    else
19365
3.95k
      BOK = BO_Add;
19366
5.30k
    break;
19367
5.13k
  case OO_Star:
19368
5.13k
    BOK = BO_Mul;
19369
5.13k
    break;
19370
4.64k
  case OO_Amp:
19371
4.64k
    BOK = BO_And;
19372
4.64k
    break;
19373
4.67k
  case OO_Pipe:
19374
4.67k
    BOK = BO_Or;
19375
4.67k
    break;
19376
4.55k
  case OO_Caret:
19377
4.55k
    BOK = BO_Xor;
19378
4.55k
    break;
19379
9.11k
  case OO_AmpAmp:
19380
9.11k
    BOK = BO_LAnd;
19381
9.11k
    break;
19382
4.12k
  case OO_PipePipe:
19383
4.12k
    BOK = BO_LOr;
19384
4.12k
    break;
19385
0
  case OO_New:
19386
0
  case OO_Delete:
19387
0
  case OO_Array_New:
19388
0
  case OO_Array_Delete:
19389
0
  case OO_Slash:
19390
0
  case OO_Percent:
19391
0
  case OO_Tilde:
19392
0
  case OO_Exclaim:
19393
0
  case OO_Equal:
19394
0
  case OO_Less:
19395
0
  case OO_Greater:
19396
0
  case OO_LessEqual:
19397
0
  case OO_GreaterEqual:
19398
0
  case OO_PlusEqual:
19399
0
  case OO_MinusEqual:
19400
0
  case OO_StarEqual:
19401
0
  case OO_SlashEqual:
19402
0
  case OO_PercentEqual:
19403
0
  case OO_CaretEqual:
19404
0
  case OO_AmpEqual:
19405
0
  case OO_PipeEqual:
19406
0
  case OO_LessLess:
19407
0
  case OO_GreaterGreater:
19408
0
  case OO_LessLessEqual:
19409
0
  case OO_GreaterGreaterEqual:
19410
0
  case OO_EqualEqual:
19411
0
  case OO_ExclaimEqual:
19412
0
  case OO_Spaceship:
19413
0
  case OO_PlusPlus:
19414
0
  case OO_MinusMinus:
19415
0
  case OO_Comma:
19416
0
  case OO_ArrowStar:
19417
0
  case OO_Arrow:
19418
0
  case OO_Call:
19419
0
  case OO_Subscript:
19420
0
  case OO_Conditional:
19421
0
  case OO_Coawait:
19422
0
  case NUM_OVERLOADED_OPERATORS:
19423
0
    llvm_unreachable("Unexpected reduction identifier");
19424
19.9k
  case OO_None:
19425
19.9k
    if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
19426
19.9k
      if (II->isStr("max"))
19427
6.86k
        BOK = BO_GT;
19428
13.0k
      else if (II->isStr("min"))
19429
8.58k
        BOK = BO_LT;
19430
19.9k
    }
19431
19.9k
    break;
19432
116k
  }
19433
19434
  // OpenMP 5.2, 5.5.5 (see page 627, line 18) reduction Clause, Restrictions
19435
  // A reduction clause with the minus (-) operator was deprecated
19436
116k
  if (OOK == OO_Minus && 
S.LangOpts.OpenMP == 525.30k
)
19437
1.39k
    S.Diag(ReductionId.getLoc(), diag::warn_omp_minus_in_reduction_deprecated);
19438
19439
116k
  SourceRange ReductionIdRange;
19440
116k
  if (ReductionIdScopeSpec.isValid())
19441
32
    ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
19442
116k
  else
19443
116k
    ReductionIdRange.setBegin(ReductionId.getBeginLoc());
19444
116k
  ReductionIdRange.setEnd(ReductionId.getEndLoc());
19445
19446
116k
  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19447
116k
  bool FirstIter = true;
19448
150k
  for (Expr *RefExpr : VarList) {
19449
150k
    assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
19450
    // OpenMP [2.1, C/C++]
19451
    //  A list item is a variable or array section, subject to the restrictions
19452
    //  specified in Section 2.4 on page 42 and in each of the sections
19453
    // describing clauses and directives for which a list appears.
19454
    // OpenMP  [2.14.3.3, Restrictions, p.1]
19455
    //  A variable that is part of another variable (as an array or
19456
    //  structure element) cannot appear in a private clause.
19457
150k
    if (!FirstIter && 
IR != ER33.9k
)
19458
10.3k
      ++IR;
19459
150k
    FirstIter = false;
19460
150k
    SourceLocation ELoc;
19461
150k
    SourceRange ERange;
19462
150k
    Expr *SimpleRefExpr = RefExpr;
19463
150k
    auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
19464
150k
                              /*AllowArraySection=*/true);
19465
150k
    if (Res.second) {
19466
      // Try to find 'declare reduction' corresponding construct before using
19467
      // builtin/overloaded operators.
19468
21.0k
      QualType Type = Context.DependentTy;
19469
21.0k
      CXXCastPath BasePath;
19470
21.0k
      ExprResult DeclareReductionRef = buildDeclareReductionRef(
19471
21.0k
          S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19472
21.0k
          ReductionId, Type, BasePath, IR == ER ? nullptr : 
*IR0
);
19473
21.0k
      Expr *ReductionOp = nullptr;
19474
21.0k
      if (S.CurContext->isDependentContext() &&
19475
21.0k
          
(21.0k
DeclareReductionRef.isUnset()21.0k
||
19476
21.0k
           isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
19477
21.0k
        ReductionOp = DeclareReductionRef.get();
19478
      // It will be analyzed later.
19479
21.0k
      RD.push(RefExpr, ReductionOp);
19480
21.0k
    }
19481
150k
    ValueDecl *D = Res.first;
19482
150k
    if (!D)
19483
26.1k
      continue;
19484
19485
124k
    Expr *TaskgroupDescriptor = nullptr;
19486
124k
    QualType Type;
19487
124k
    auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19488
124k
    auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
19489
124k
    if (ASE) {
19490
443
      Type = ASE->getType().getNonReferenceType();
19491
123k
    } else if (OASE) {
19492
714
      QualType BaseType =
19493
714
          OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19494
714
      if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19495
567
        Type = ATy->getElementType();
19496
147
      else
19497
147
        Type = BaseType->getPointeeType();
19498
714
      Type = Type.getNonReferenceType();
19499
123k
    } else {
19500
123k
      Type = Context.getBaseElementType(D->getType().getNonReferenceType());
19501
123k
    }
19502
124k
    auto *VD = dyn_cast<VarDecl>(D);
19503
19504
    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
19505
    //  A variable that appears in a private clause must not have an incomplete
19506
    //  type or a reference type.
19507
124k
    if (S.RequireCompleteType(ELoc, D->getType(),
19508
124k
                              diag::err_omp_reduction_incomplete_type))
19509
4.10k
      continue;
19510
    // OpenMP [2.14.3.6, reduction clause, Restrictions]
19511
    // A list item that appears in a reduction clause must not be
19512
    // const-qualified.
19513
120k
    if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
19514
120k
                                  /*AcceptIfMutable*/ false, ASE || 
OASE119k
))
19515
22.5k
      continue;
19516
19517
97.5k
    OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
19518
    // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
19519
    //  If a list-item is a reference type then it must bind to the same object
19520
    //  for all threads of the team.
19521
97.5k
    if (!ASE && 
!OASE97.1k
) {
19522
96.4k
      if (VD) {
19523
96.0k
        VarDecl *VDDef = VD->getDefinition();
19524
96.0k
        if (VD->getType()->isReferenceType() && 
VDDef23.2k
&&
VDDef->hasInit()23.2k
) {
19525
21.4k
          DSARefChecker Check(Stack);
19526
21.4k
          if (Check.Visit(VDDef->getInit())) {
19527
12.5k
            S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19528
12.5k
                << getOpenMPClauseName(ClauseKind) << ERange;
19529
12.5k
            S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
19530
12.5k
            continue;
19531
12.5k
          }
19532
21.4k
        }
19533
96.0k
      }
19534
19535
      // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
19536
      // in a Construct]
19537
      //  Variables with the predetermined data-sharing attributes may not be
19538
      //  listed in data-sharing attributes clauses, except for the cases
19539
      //  listed below. For these exceptions only, listing a predetermined
19540
      //  variable in a data-sharing attribute clause is allowed and overrides
19541
      //  the variable's predetermined data-sharing attributes.
19542
      // OpenMP [2.14.3.6, Restrictions, p.3]
19543
      //  Any number of reduction clauses can be specified on the directive,
19544
      //  but a list item can appear only once in the reduction clauses for that
19545
      //  directive.
19546
83.8k
      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19547
83.8k
      if (DVar.CKind == OMPC_reduction) {
19548
3.08k
        S.Diag(ELoc, diag::err_omp_once_referenced)
19549
3.08k
            << getOpenMPClauseName(ClauseKind);
19550
3.08k
        if (DVar.RefExpr)
19551
3.08k
          S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19552
3.08k
        continue;
19553
3.08k
      }
19554
80.8k
      if (DVar.CKind != OMPC_unknown) {
19555
5.13k
        S.Diag(ELoc, diag::err_omp_wrong_dsa)
19556
5.13k
            << getOpenMPClauseName(DVar.CKind)
19557
5.13k
            << getOpenMPClauseName(OMPC_reduction);
19558
5.13k
        reportOriginalDsa(S, Stack, D, DVar);
19559
5.13k
        continue;
19560
5.13k
      }
19561
19562
      // OpenMP [2.14.3.6, Restrictions, p.1]
19563
      //  A list item that appears in a reduction clause of a worksharing
19564
      //  construct must be shared in the parallel regions to which any of the
19565
      //  worksharing regions arising from the worksharing construct bind.
19566
75.6k
      if (isOpenMPWorksharingDirective(CurrDir) &&
19567
75.6k
          
!isOpenMPParallelDirective(CurrDir)21.4k
&&
19568
75.6k
          
!isOpenMPTeamsDirective(CurrDir)5.16k
) {
19569
5.15k
        DVar = Stack->getImplicitDSA(D, true);
19570
5.15k
        if (DVar.CKind != OMPC_shared) {
19571
529
          S.Diag(ELoc, diag::err_omp_required_access)
19572
529
              << getOpenMPClauseName(OMPC_reduction)
19573
529
              << getOpenMPClauseName(OMPC_shared);
19574
529
          reportOriginalDsa(S, Stack, D, DVar);
19575
529
          continue;
19576
529
        }
19577
5.15k
      }
19578
75.6k
    } else {
19579
      // Threadprivates cannot be shared between threads, so dignose if the base
19580
      // is a threadprivate variable.
19581
1.15k
      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19582
1.15k
      if (DVar.CKind == OMPC_threadprivate) {
19583
24
        S.Diag(ELoc, diag::err_omp_wrong_dsa)
19584
24
            << getOpenMPClauseName(DVar.CKind)
19585
24
            << getOpenMPClauseName(OMPC_reduction);
19586
24
        reportOriginalDsa(S, Stack, D, DVar);
19587
24
        continue;
19588
24
      }
19589
1.15k
    }
19590
19591
    // Try to find 'declare reduction' corresponding construct before using
19592
    // builtin/overloaded operators.
19593
76.2k
    CXXCastPath BasePath;
19594
76.2k
    ExprResult DeclareReductionRef = buildDeclareReductionRef(
19595
76.2k
        S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19596
76.2k
        ReductionId, Type, BasePath, IR == ER ? 
nullptr36.2k
:
*IR40.0k
);
19597
76.2k
    if (DeclareReductionRef.isInvalid())
19598
2
      continue;
19599
76.2k
    if (S.CurContext->isDependentContext() &&
19600
76.2k
        
(8.96k
DeclareReductionRef.isUnset()8.96k
||
19601
8.96k
         isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
19602
8.96k
      RD.push(RefExpr, DeclareReductionRef.get());
19603
8.96k
      continue;
19604
8.96k
    }
19605
67.3k
    if (BOK == BO_Comma && 
DeclareReductionRef.isUnset()3.61k
) {
19606
      // Not allowed reduction identifier is found.
19607
3.31k
      if (S.LangOpts.OpenMP > 52)
19608
1.02k
        S.Diag(ReductionId.getBeginLoc(),
19609
1.02k
               diag::err_omp_unknown_reduction_identifier_since_omp_6_0)
19610
1.02k
            << Type << ReductionIdRange;
19611
2.29k
      else
19612
2.29k
        S.Diag(ReductionId.getBeginLoc(),
19613
2.29k
               diag::err_omp_unknown_reduction_identifier_prior_omp_6_0)
19614
2.29k
            << Type << ReductionIdRange;
19615
3.31k
      continue;
19616
3.31k
    }
19617
19618
    // OpenMP [2.14.3.6, reduction clause, Restrictions]
19619
    // The type of a list item that appears in a reduction clause must be valid
19620
    // for the reduction-identifier. For a max or min reduction in C, the type
19621
    // of the list item must be an allowed arithmetic data type: char, int,
19622
    // float, double, or _Bool, possibly modified with long, short, signed, or
19623
    // unsigned. For a max or min reduction in C++, the type of the list item
19624
    // must be an allowed arithmetic data type: char, wchar_t, int, float,
19625
    // double, or bool, possibly modified with long, short, signed, or unsigned.
19626
63.9k
    if (DeclareReductionRef.isUnset()) {
19627
63.5k
      if ((BOK == BO_GT || 
BOK == BO_LT62.8k
) &&
19628
63.5k
          
!(10.4k
Type->isScalarType()10.4k
||
19629
10.4k
            
(6.16k
S.getLangOpts().CPlusPlus6.16k
&&
Type->isArithmeticType()6.16k
))) {
19630
6.16k
        S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19631
6.16k
            << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
19632
6.16k
        if (!ASE && !OASE) {
19633
6.16k
          bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19634
6.16k
                                   VarDecl::DeclarationOnly;
19635
6.16k
          S.Diag(D->getLocation(),
19636
6.16k
                 IsDecl ? 
diag::note_previous_decl0
: diag::note_defined_here)
19637
6.16k
              << D;
19638
6.16k
        }
19639
6.16k
        continue;
19640
6.16k
      }
19641
57.4k
      if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19642
57.4k
          
!S.getLangOpts().CPlusPlus0
&&
Type->isFloatingType()0
) {
19643
0
        S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19644
0
            << getOpenMPClauseName(ClauseKind);
19645
0
        if (!ASE && !OASE) {
19646
0
          bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19647
0
                                   VarDecl::DeclarationOnly;
19648
0
          S.Diag(D->getLocation(),
19649
0
                 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19650
0
              << D;
19651
0
        }
19652
0
        continue;
19653
0
      }
19654
57.4k
    }
19655
19656
57.8k
    Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
19657
57.8k
    VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
19658
57.8k
                                  D->hasAttrs() ? 
&D->getAttrs()20
:
nullptr57.8k
);
19659
57.8k
    VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
19660
57.8k
                                  D->hasAttrs() ? 
&D->getAttrs()20
:
nullptr57.8k
);
19661
57.8k
    QualType PrivateTy = Type;
19662
19663
    // Try if we can determine constant lengths for all array sections and avoid
19664
    // the VLA.
19665
57.8k
    bool ConstantLengthOASE = false;
19666
57.8k
    if (OASE) {
19667
690
      bool SingleElement;
19668
690
      llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
19669
690
      ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
19670
690
          Context, OASE, SingleElement, ArraySizes);
19671
19672
      // If we don't have a single element, we must emit a constant array type.
19673
690
      if (ConstantLengthOASE && 
!SingleElement141
) {
19674
123
        for (llvm::APSInt &Size : ArraySizes)
19675
167
          PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
19676
167
                                                   ArraySizeModifier::Normal,
19677
167
                                                   /*IndexTypeQuals=*/0);
19678
123
      }
19679
690
    }
19680
19681
57.8k
    if ((OASE && 
!ConstantLengthOASE690
) ||
19682
57.8k
        
(57.2k
!OASE57.2k
&&
!ASE57.1k
&&
19683
57.2k
         
D->getType().getNonReferenceType()->isVariablyModifiedType()56.7k
)) {
19684
674
      if (!Context.getTargetInfo().isVLASupported()) {
19685
11
        if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
19686
1
          S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19687
1
          S.Diag(ELoc, diag::note_vla_unsupported);
19688
1
          continue;
19689
10
        } else {
19690
10
          S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19691
10
          S.targetDiag(ELoc, diag::note_vla_unsupported);
19692
10
        }
19693
11
      }
19694
      // For arrays/array sections only:
19695
      // Create pseudo array type for private copy. The size for this array will
19696
      // be generated during codegen.
19697
      // For array subscripts or single variables Private Ty is the same as Type
19698
      // (type of the variable or single array element).
19699
673
      PrivateTy = Context.getVariableArrayType(
19700
673
          Type,
19701
673
          new (Context)
19702
673
              OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
19703
673
          ArraySizeModifier::Normal, /*IndexTypeQuals=*/0, SourceRange());
19704
57.1k
    } else if (!ASE && 
!OASE56.7k
&&
19705
57.1k
               
Context.getAsArrayType(D->getType().getNonReferenceType())56.5k
) {
19706
134
      PrivateTy = D->getType().getNonReferenceType();
19707
134
    }
19708
    // Private copy.
19709
57.8k
    VarDecl *PrivateVD =
19710
57.8k
        buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19711
57.8k
                     D->hasAttrs() ? 
&D->getAttrs()20
:
nullptr57.8k
,
19712
57.8k
                     VD ? 
cast<DeclRefExpr>(SimpleRefExpr)57.4k
:
nullptr430
);
19713
    // Add initializer for private variable.
19714
57.8k
    Expr *Init = nullptr;
19715
57.8k
    DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
19716
57.8k
    DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
19717
57.8k
    if (DeclareReductionRef.isUsable()) {
19718
412
      auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
19719
412
      auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19720
412
      if (DRD->getInitializer()) {
19721
98
        Init = DRDRef;
19722
98
        RHSVD->setInit(DRDRef);
19723
98
        RHSVD->setInitStyle(VarDecl::CallInit);
19724
98
      }
19725
57.4k
    } else {
19726
57.4k
      switch (BOK) {
19727
34.5k
      case BO_Add:
19728
38.2k
      case BO_Xor:
19729
41.7k
      case BO_Or:
19730
41.8k
      case BO_LOr:
19731
        // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
19732
41.8k
        if (Type->isScalarType() || 
Type->isAnyComplexType()16.6k
)
19733
25.1k
          Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
19734
41.8k
        break;
19735
2.37k
      case BO_Mul:
19736
6.84k
      case BO_LAnd:
19737
6.84k
        if (Type->isScalarType() || 
Type->isAnyComplexType()100
) {
19738
          // '*' and '&&' reduction ops - initializer is '1'.
19739
6.74k
          Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
19740
6.74k
        }
19741
6.84k
        break;
19742
4.46k
      case BO_And: {
19743
        // '&' reduction op - initializer is '~0'.
19744
4.46k
        QualType OrigType = Type;
19745
4.46k
        if (auto *ComplexTy = OrigType->getAs<ComplexType>())
19746
0
          Type = ComplexTy->getElementType();
19747
4.46k
        if (Type->isRealFloatingType()) {
19748
1.13k
          llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19749
1.13k
              Context.getFloatTypeSemantics(Type));
19750
1.13k
          Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19751
1.13k
                                         Type, ELoc);
19752
3.32k
        } else if (Type->isScalarType()) {
19753
1.19k
          uint64_t Size = Context.getTypeSize(Type);
19754
1.19k
          QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
19755
1.19k
          llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19756
1.19k
          Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19757
1.19k
        }
19758
4.46k
        if (Init && 
OrigType->isAnyComplexType()2.33k
) {
19759
          // Init = 0xFFFF + 0xFFFFi;
19760
0
          auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
19761
0
          Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
19762
0
        }
19763
4.46k
        Type = OrigType;
19764
4.46k
        break;
19765
2.37k
      }
19766
3.59k
      case BO_LT:
19767
4.30k
      case BO_GT: {
19768
        // 'min' reduction op - initializer is 'Largest representable number in
19769
        // the reduction list item type'.
19770
        // 'max' reduction op - initializer is 'Least representable number in
19771
        // the reduction list item type'.
19772
4.30k
        if (Type->isIntegerType() || 
Type->isPointerType()1.16k
) {
19773
3.16k
          bool IsSigned = Type->hasSignedIntegerRepresentation();
19774
3.16k
          uint64_t Size = Context.getTypeSize(Type);
19775
3.16k
          QualType IntTy =
19776
3.16k
              Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
19777
3.16k
          llvm::APInt InitValue =
19778
3.16k
              (BOK != BO_LT) ? 
IsSigned688
?
llvm::APInt::getSignedMinValue(Size)664
19779
688
                                        : 
llvm::APInt::getMinValue(Size)24
19780
3.16k
              : 
IsSigned2.47k
?
llvm::APInt::getSignedMaxValue(Size)2.47k
19781
2.47k
                             : 
llvm::APInt::getMaxValue(Size)0
;
19782
3.16k
          Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19783
3.16k
          if (Type->isPointerType()) {
19784
            // Cast to pointer type.
19785
24
            ExprResult CastExpr = S.BuildCStyleCastExpr(
19786
24
                ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
19787
24
            if (CastExpr.isInvalid())
19788
0
              continue;
19789
24
            Init = CastExpr.get();
19790
24
          }
19791
3.16k
        } else 
if (1.13k
Type->isRealFloatingType()1.13k
) {
19792
1.13k
          llvm::APFloat InitValue = llvm::APFloat::getLargest(
19793
1.13k
              Context.getFloatTypeSemantics(Type), BOK != BO_LT);
19794
1.13k
          Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19795
1.13k
                                         Type, ELoc);
19796
1.13k
        }
19797
4.30k
        break;
19798
4.30k
      }
19799
4.30k
      case BO_PtrMemD:
19800
0
      case BO_PtrMemI:
19801
0
      case BO_MulAssign:
19802
0
      case BO_Div:
19803
0
      case BO_Rem:
19804
0
      case BO_Sub:
19805
0
      case BO_Shl:
19806
0
      case BO_Shr:
19807
0
      case BO_LE:
19808
0
      case BO_GE:
19809
0
      case BO_EQ:
19810
0
      case BO_NE:
19811
0
      case BO_Cmp:
19812
0
      case BO_AndAssign:
19813
0
      case BO_XorAssign:
19814
0
      case BO_OrAssign:
19815
0
      case BO_Assign:
19816
0
      case BO_AddAssign:
19817
0
      case BO_SubAssign:
19818
0
      case BO_DivAssign:
19819
0
      case BO_RemAssign:
19820
0
      case BO_ShlAssign:
19821
0
      case BO_ShrAssign:
19822
0
      case BO_Comma:
19823
0
        llvm_unreachable("Unexpected reduction operation");
19824
57.4k
      }
19825
57.4k
    }
19826
57.8k
    if (Init && 
DeclareReductionRef.isUnset()38.6k
) {
19827
38.5k
      S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
19828
      // Store initializer for single element in private copy. Will be used
19829
      // during codegen.
19830
38.5k
      PrivateVD->setInit(RHSVD->getInit());
19831
38.5k
      PrivateVD->setInitStyle(RHSVD->getInitStyle());
19832
38.5k
    } else 
if (19.2k
!Init19.2k
) {
19833
19.2k
      S.ActOnUninitializedDecl(RHSVD);
19834
      // Store initializer for single element in private copy. Will be used
19835
      // during codegen.
19836
19.2k
      PrivateVD->setInit(RHSVD->getInit());
19837
19.2k
      PrivateVD->setInitStyle(RHSVD->getInitStyle());
19838
19.2k
    }
19839
57.8k
    if (RHSVD->isInvalidDecl())
19840
0
      continue;
19841
57.8k
    if (!RHSVD->hasInit() && 
DeclareReductionRef.isUnset()294
) {
19842
0
      S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19843
0
          << Type << ReductionIdRange;
19844
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19845
0
                               VarDecl::DeclarationOnly;
19846
0
      S.Diag(D->getLocation(),
19847
0
             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19848
0
          << D;
19849
0
      continue;
19850
0
    }
19851
57.8k
    DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
19852
57.8k
    ExprResult ReductionOp;
19853
57.8k
    if (DeclareReductionRef.isUsable()) {
19854
412
      QualType RedTy = DeclareReductionRef.get()->getType();
19855
412
      QualType PtrRedTy = Context.getPointerType(RedTy);
19856
412
      ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
19857
412
      ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
19858
412
      if (!BasePath.empty()) {
19859
36
        LHS = S.DefaultLvalueConversion(LHS.get());
19860
36
        RHS = S.DefaultLvalueConversion(RHS.get());
19861
36
        LHS = ImplicitCastExpr::Create(
19862
36
            Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
19863
36
            LHS.get()->getValueKind(), FPOptionsOverride());
19864
36
        RHS = ImplicitCastExpr::Create(
19865
36
            Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
19866
36
            RHS.get()->getValueKind(), FPOptionsOverride());
19867
36
      }
19868
412
      FunctionProtoType::ExtProtoInfo EPI;
19869
412
      QualType Params[] = {PtrRedTy, PtrRedTy};
19870
412
      QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
19871
412
      auto *OVE = new (Context) OpaqueValueExpr(
19872
412
          ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
19873
412
          S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
19874
412
      Expr *Args[] = {LHS.get(), RHS.get()};
19875
412
      ReductionOp =
19876
412
          CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
19877
412
                           S.CurFPFeatureOverrides());
19878
57.4k
    } else {
19879
57.4k
      BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
19880
57.4k
      if (Type->isRecordType() && 
CombBOK != BOK18.8k
) {
19881
18.8k
        Sema::TentativeAnalysisScope Trap(S);
19882
18.8k
        ReductionOp =
19883
18.8k
            S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19884
18.8k
                         CombBOK, LHSDRE, RHSDRE);
19885
18.8k
      }
19886
57.4k
      if (!ReductionOp.isUsable()) {
19887
56.3k
        ReductionOp =
19888
56.3k
            S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
19889
56.3k
                         LHSDRE, RHSDRE);
19890
56.3k
        if (ReductionOp.isUsable()) {
19891
50.9k
          if (BOK != BO_LT && 
BOK != BO_GT47.3k
) {
19892
46.6k
            ReductionOp =
19893
46.6k
                S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19894
46.6k
                             BO_Assign, LHSDRE, ReductionOp.get());
19895
46.6k
          } else {
19896
4.30k
            auto *ConditionalOp = new (Context)
19897
4.30k
                ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
19898
4.30k
                                    RHSDRE, Type, VK_LValue, OK_Ordinary);
19899
4.30k
            ReductionOp =
19900
4.30k
                S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19901
4.30k
                             BO_Assign, LHSDRE, ConditionalOp);
19902
4.30k
          }
19903
50.9k
        }
19904
56.3k
      }
19905
57.4k
      if (ReductionOp.isUsable())
19906
48.9k
        ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
19907
48.9k
                                            /*DiscardedValue*/ false);
19908
57.4k
      if (!ReductionOp.isUsable())
19909
8.46k
        continue;
19910
57.4k
    }
19911
19912
    // Add copy operations for inscan reductions.
19913
    // LHS = RHS;
19914
49.3k
    ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
19915
49.3k
    if (ClauseKind == OMPC_reduction &&
19916
49.3k
        
RD.RedModifier == OMPC_REDUCTION_inscan39.0k
) {
19917
311
      ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
19918
311
      CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
19919
311
                               RHS.get());
19920
311
      if (!CopyOpRes.isUsable())
19921
0
        continue;
19922
311
      CopyOpRes =
19923
311
          S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
19924
311
      if (!CopyOpRes.isUsable())
19925
0
        continue;
19926
      // For simd directive and simd-based directives in simd mode no need to
19927
      // construct temp array, need just a single temp element.
19928
311
      if (Stack->getCurrentDirective() == OMPD_simd ||
19929
311
          
(269
S.getLangOpts().OpenMPSimd269
&&
19930
269
           
isOpenMPSimdDirective(Stack->getCurrentDirective())121
)) {
19931
62
        VarDecl *TempArrayVD =
19932
62
            buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19933
62
                         D->hasAttrs() ? 
&D->getAttrs()0
: nullptr);
19934
        // Add a constructor to the temp decl.
19935
62
        S.ActOnUninitializedDecl(TempArrayVD);
19936
62
        TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
19937
249
      } else {
19938
        // Build temp array for prefix sum.
19939
249
        auto *Dim = new (S.Context)
19940
249
            OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19941
249
        QualType ArrayTy = S.Context.getVariableArrayType(
19942
249
            PrivateTy, Dim, ArraySizeModifier::Normal,
19943
249
            /*IndexTypeQuals=*/0, {ELoc, ELoc});
19944
249
        VarDecl *TempArrayVD =
19945
249
            buildVarDecl(S, ELoc, ArrayTy, D->getName(),
19946
249
                         D->hasAttrs() ? 
&D->getAttrs()0
: nullptr);
19947
        // Add a constructor to the temp decl.
19948
249
        S.ActOnUninitializedDecl(TempArrayVD);
19949
249
        TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
19950
249
        TempArrayElem =
19951
249
            S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
19952
249
        auto *Idx = new (S.Context)
19953
249
            OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19954
249
        TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
19955
249
                                                          ELoc, Idx, ELoc);
19956
249
      }
19957
311
    }
19958
19959
    // OpenMP [2.15.4.6, Restrictions, p.2]
19960
    // A list item that appears in an in_reduction clause of a task construct
19961
    // must appear in a task_reduction clause of a construct associated with a
19962
    // taskgroup region that includes the participating task in its taskgroup
19963
    // set. The construct associated with the innermost region that meets this
19964
    // condition must specify the same reduction-identifier as the in_reduction
19965
    // clause.
19966
49.3k
    if (ClauseKind == OMPC_in_reduction) {
19967
4.35k
      SourceRange ParentSR;
19968
4.35k
      BinaryOperatorKind ParentBOK;
19969
4.35k
      const Expr *ParentReductionOp = nullptr;
19970
4.35k
      Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
19971
4.35k
      DSAStackTy::DSAVarData ParentBOKDSA =
19972
4.35k
          Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
19973
4.35k
                                                  ParentBOKTD);
19974
4.35k
      DSAStackTy::DSAVarData ParentReductionOpDSA =
19975
4.35k
          Stack->getTopMostTaskgroupReductionData(
19976
4.35k
              D, ParentSR, ParentReductionOp, ParentReductionOpTD);
19977
4.35k
      bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
19978
4.35k
      bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
19979
4.35k
      if ((DeclareReductionRef.isUnset() && 
IsParentReductionOp4.23k
) ||
19980
4.35k
          
(4.23k
DeclareReductionRef.isUsable()4.23k
&&
IsParentBOK120
) ||
19981
4.35k
          
(4.11k
IsParentBOK4.11k
&&
BOK != ParentBOK3.38k
) ||
IsParentReductionOp3.88k
) {
19982
468
        bool EmitError = true;
19983
468
        if (IsParentReductionOp && 
DeclareReductionRef.isUsable()120
) {
19984
0
          llvm::FoldingSetNodeID RedId, ParentRedId;
19985
0
          ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
19986
0
          DeclareReductionRef.get()->Profile(RedId, Context,
19987
0
                                             /*Canonical=*/true);
19988
0
          EmitError = RedId != ParentRedId;
19989
0
        }
19990
468
        if (EmitError) {
19991
468
          S.Diag(ReductionId.getBeginLoc(),
19992
468
                 diag::err_omp_reduction_identifier_mismatch)
19993
468
              << ReductionIdRange << RefExpr->getSourceRange();
19994
468
          S.Diag(ParentSR.getBegin(),
19995
468
                 diag::note_omp_previous_reduction_identifier)
19996
468
              << ParentSR
19997
468
              << (IsParentBOK ? 
ParentBOKDSA.RefExpr348
19998
468
                              : 
ParentReductionOpDSA.RefExpr120
)
19999
468
                     ->getSourceRange();
20000
468
          continue;
20001
468
        }
20002
468
      }
20003
3.88k
      TaskgroupDescriptor = IsParentBOK ? 
ParentBOKTD3.15k
:
ParentReductionOpTD728
;
20004
3.88k
    }
20005
20006
48.9k
    DeclRefExpr *Ref = nullptr;
20007
48.9k
    Expr *VarsExpr = RefExpr->IgnoreParens();
20008
48.9k
    if (!VD && 
!S.CurContext->isDependentContext()430
) {
20009
430
      if (ASE || OASE) {
20010
60
        TransformExprToCaptures RebuildToCapture(S, D);
20011
60
        VarsExpr =
20012
60
            RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
20013
60
        Ref = RebuildToCapture.getCapturedExpr();
20014
370
      } else {
20015
370
        VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
20016
370
      }
20017
430
      if (!S.isOpenMPCapturedDecl(D)) {
20018
414
        RD.ExprCaptures.emplace_back(Ref->getDecl());
20019
414
        if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20020
228
          ExprResult RefRes = S.DefaultLvalueConversion(Ref);
20021
228
          if (!RefRes.isUsable())
20022
0
            continue;
20023
228
          ExprResult PostUpdateRes =
20024
228
              S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
20025
228
                           RefRes.get());
20026
228
          if (!PostUpdateRes.isUsable())
20027
0
            continue;
20028
228
          if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
20029
228
              
Stack->getCurrentDirective() == OMPD_taskgroup8
) {
20030
220
            S.Diag(RefExpr->getExprLoc(),
20031
220
                   diag::err_omp_reduction_non_addressable_expression)
20032
220
                << RefExpr->getSourceRange();
20033
220
            continue;
20034
220
          }
20035
8
          RD.ExprPostUpdates.emplace_back(
20036
8
              S.IgnoredValueConversions(PostUpdateRes.get()).get());
20037
8
        }
20038
414
      }
20039
430
    }
20040
    // All reduction items are still marked as reduction (to do not increase
20041
    // code base size).
20042
48.6k
    unsigned Modifier = RD.RedModifier;
20043
    // Consider task_reductions as reductions with task modifier. Required for
20044
    // correct analysis of in_reduction clauses.
20045
48.6k
    if (CurrDir == OMPD_taskgroup && 
ClauseKind == OMPC_task_reduction5.99k
)
20046
5.99k
      Modifier = OMPC_REDUCTION_task;
20047
48.6k
    Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
20048
48.6k
                  ASE || 
OASE48.2k
);
20049
48.6k
    if (Modifier == OMPC_REDUCTION_task &&
20050
48.6k
        
(6.89k
CurrDir == OMPD_taskgroup6.89k
||
20051
6.89k
         
(900
(900
isOpenMPParallelDirective(CurrDir)900
||
20052
900
           
isOpenMPWorksharingDirective(CurrDir)382
) &&
20053
6.46k
          
!isOpenMPSimdDirective(CurrDir)608
))) {
20054
6.46k
      if (DeclareReductionRef.isUsable())
20055
120
        Stack->addTaskgroupReductionData(D, ReductionIdRange,
20056
120
                                         DeclareReductionRef.get());
20057
6.34k
      else
20058
6.34k
        Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
20059
6.46k
    }
20060
48.6k
    RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
20061
48.6k
            TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
20062
48.6k
            TempArrayElem.get());
20063
48.6k
  }
20064
116k
  return RD.Vars.empty();
20065
116k
}
20066
20067
OMPClause *Sema::ActOnOpenMPReductionClause(
20068
    ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
20069
    SourceLocation StartLoc, SourceLocation LParenLoc,
20070
    SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
20071
    CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20072
96.2k
    ArrayRef<Expr *> UnresolvedReductions) {
20073
96.2k
  if (ModifierLoc.isValid() && 
Modifier == OMPC_REDUCTION_unknown1.18k
) {
20074
1
    Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
20075
1
        << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
20076
1
                                   /*Last=*/OMPC_REDUCTION_unknown)
20077
1
        << getOpenMPClauseName(OMPC_reduction);
20078
1
    return nullptr;
20079
1
  }
20080
  // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
20081
  // A reduction clause with the inscan reduction-modifier may only appear on a
20082
  // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
20083
  // construct, a parallel worksharing-loop construct or a parallel
20084
  // worksharing-loop SIMD construct.
20085
96.2k
  if (Modifier == OMPC_REDUCTION_inscan &&
20086
96.2k
      
(214
DSAStack214
->getCurrentDirective() != OMPD_for214
&&
20087
214
       
DSAStack194
->getCurrentDirective() != OMPD_for_simd194
&&
20088
214
       
DSAStack180
->getCurrentDirective() != OMPD_simd180
&&
20089
214
       
DSAStack122
->getCurrentDirective() != OMPD_parallel_for122
&&
20090
214
       
DSAStack9
->getCurrentDirective() != OMPD_parallel_for_simd9
)) {
20091
1
    Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
20092
1
    return nullptr;
20093
1
  }
20094
20095
96.2k
  ReductionData RD(VarList.size(), Modifier);
20096
96.2k
  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
20097
96.2k
                                  StartLoc, LParenLoc, ColonLoc, EndLoc,
20098
96.2k
                                  ReductionIdScopeSpec, ReductionId,
20099
96.2k
                                  UnresolvedReductions, RD))
20100
42.9k
    return nullptr;
20101
20102
53.2k
  return OMPReductionClause::Create(
20103
53.2k
      Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
20104
53.2k
      RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20105
53.2k
      RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
20106
53.2k
      RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
20107
53.2k
      buildPreInits(Context, RD.ExprCaptures),
20108
53.2k
      buildPostUpdate(*this, RD.ExprPostUpdates));
20109
96.2k
}
20110
20111
OMPClause *Sema::ActOnOpenMPTaskReductionClause(
20112
    ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
20113
    SourceLocation ColonLoc, SourceLocation EndLoc,
20114
    CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20115
9.04k
    ArrayRef<Expr *> UnresolvedReductions) {
20116
9.04k
  ReductionData RD(VarList.size());
20117
9.04k
  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
20118
9.04k
                                  StartLoc, LParenLoc, ColonLoc, EndLoc,
20119
9.04k
                                  ReductionIdScopeSpec, ReductionId,
20120
9.04k
                                  UnresolvedReductions, RD))
20121
942
    return nullptr;
20122
20123
8.09k
  return OMPTaskReductionClause::Create(
20124
8.09k
      Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20125
8.09k
      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20126
8.09k
      RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
20127
8.09k
      buildPreInits(Context, RD.ExprCaptures),
20128
8.09k
      buildPostUpdate(*this, RD.ExprPostUpdates));
20129
9.04k
}
20130
20131
OMPClause *Sema::ActOnOpenMPInReductionClause(
20132
    ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
20133
    SourceLocation ColonLoc, SourceLocation EndLoc,
20134
    CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20135
11.1k
    ArrayRef<Expr *> UnresolvedReductions) {
20136
11.1k
  ReductionData RD(VarList.size());
20137
11.1k
  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
20138
11.1k
                                  StartLoc, LParenLoc, ColonLoc, EndLoc,
20139
11.1k
                                  ReductionIdScopeSpec, ReductionId,
20140
11.1k
                                  UnresolvedReductions, RD))
20141
5.54k
    return nullptr;
20142
20143
5.61k
  return OMPInReductionClause::Create(
20144
5.61k
      Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20145
5.61k
      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20146
5.61k
      RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
20147
5.61k
      buildPreInits(Context, RD.ExprCaptures),
20148
5.61k
      buildPostUpdate(*this, RD.ExprPostUpdates));
20149
11.1k
}
20150
20151
bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
20152
6.14k
                                     SourceLocation LinLoc) {
20153
6.14k
  if ((!LangOpts.CPlusPlus && 
LinKind != OMPC_LINEAR_val459
) ||
20154
6.14k
      
LinKind == OMPC_LINEAR_unknown6.10k
||
LinKind == OMPC_LINEAR_step6.07k
) {
20155
62
    Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
20156
62
    return true;
20157
62
  }
20158
6.07k
  return false;
20159
6.14k
}
20160
20161
bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
20162
                                 OpenMPLinearClauseKind LinKind, QualType Type,
20163
5.68k
                                 bool IsDeclareSimd) {
20164
5.68k
  const auto *VD = dyn_cast_or_null<VarDecl>(D);
20165
  // A variable must not have an incomplete type or a reference type.
20166
5.68k
  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
20167
152
    return true;
20168
5.53k
  if ((LinKind == OMPC_LINEAR_uval || 
LinKind == OMPC_LINEAR_ref5.35k
) &&
20169
5.53k
      
!Type->isReferenceType()382
) {
20170
106
    Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
20171
106
        << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
20172
106
    return true;
20173
106
  }
20174
5.43k
  Type = Type.getNonReferenceType();
20175
20176
  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
20177
  // A variable that is privatized must not have a const-qualified type
20178
  // unless it is of class type with a mutable member. This restriction does
20179
  // not apply to the firstprivate clause, nor to the linear clause on
20180
  // declarative directives (like declare simd).
20181
5.43k
  if (!IsDeclareSimd &&
20182
5.43k
      
rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)5.13k
)
20183
0
    return true;
20184
20185
  // A list item must be of integral or pointer type.
20186
5.43k
  Type = Type.getUnqualifiedType().getCanonicalType();
20187
5.43k
  const auto *Ty = Type.getTypePtrOrNull();
20188
5.43k
  if (!Ty || (LinKind != OMPC_LINEAR_ref && 
!Ty->isDependentType()5.28k
&&
20189
5.43k
              
!Ty->isIntegralType(Context)5.28k
&&
!Ty->isPointerType()610
)) {
20190
380
    Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
20191
380
    if (D) {
20192
380
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20193
380
                               VarDecl::DeclarationOnly;
20194
380
      Diag(D->getLocation(),
20195
380
           IsDecl ? 
diag::note_previous_decl0
: diag::note_defined_here)
20196
380
          << D;
20197
380
    }
20198
380
    return true;
20199
380
  }
20200
5.05k
  return false;
20201
5.43k
}
20202
20203
OMPClause *Sema::ActOnOpenMPLinearClause(
20204
    ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
20205
    SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
20206
    SourceLocation LinLoc, SourceLocation ColonLoc,
20207
5.85k
    SourceLocation StepModifierLoc, SourceLocation EndLoc) {
20208
5.85k
  SmallVector<Expr *, 8> Vars;
20209
5.85k
  SmallVector<Expr *, 8> Privates;
20210
5.85k
  SmallVector<Expr *, 8> Inits;
20211
5.85k
  SmallVector<Decl *, 4> ExprCaptures;
20212
5.85k
  SmallVector<Expr *, 4> ExprPostUpdates;
20213
  // OpenMP 5.2 [Section 5.4.6, linear clause]
20214
  // step-simple-modifier is exclusive, can't be used with 'val', 'uval', or
20215
  // 'ref'
20216
5.85k
  if (LinLoc.isValid() && 
StepModifierLoc.isInvalid()646
&&
Step602
&&
20217
5.85k
      
getLangOpts().OpenMP >= 5268
)
20218
12
    Diag(Step->getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
20219
5.85k
  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
20220
60
    LinKind = OMPC_LINEAR_val;
20221
6.98k
  for (Expr *RefExpr : VarList) {
20222
6.98k
    assert(RefExpr && "NULL expr in OpenMP linear clause.");
20223
6.98k
    SourceLocation ELoc;
20224
6.98k
    SourceRange ERange;
20225
6.98k
    Expr *SimpleRefExpr = RefExpr;
20226
6.98k
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20227
6.98k
    if (Res.second) {
20228
      // It will be analyzed later.
20229
884
      Vars.push_back(RefExpr);
20230
884
      Privates.push_back(nullptr);
20231
884
      Inits.push_back(nullptr);
20232
884
    }
20233
6.98k
    ValueDecl *D = Res.first;
20234
6.98k
    if (!D)
20235
1.29k
      continue;
20236
20237
5.69k
    QualType Type = D->getType();
20238
5.69k
    auto *VD = dyn_cast<VarDecl>(D);
20239
20240
    // OpenMP [2.14.3.7, linear clause]
20241
    //  A list-item cannot appear in more than one linear clause.
20242
    //  A list-item that appears in a linear clause cannot appear in any
20243
    //  other data-sharing attribute clause.
20244
5.69k
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
20245
5.69k
    if (DVar.RefExpr) {
20246
306
      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
20247
306
                                          << getOpenMPClauseName(OMPC_linear);
20248
306
      reportOriginalDsa(*this, DSAStack, D, DVar);
20249
306
      continue;
20250
306
    }
20251
20252
5.38k
    if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
20253
634
      continue;
20254
4.75k
    Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20255
20256
    // Build private copy of original var.
20257
4.75k
    VarDecl *Private =
20258
4.75k
        buildVarDecl(*this, ELoc, Type, D->getName(),
20259
4.75k
                     D->hasAttrs() ? 
&D->getAttrs()0
: nullptr,
20260
4.75k
                     VD ? 
cast<DeclRefExpr>(SimpleRefExpr)4.67k
:
nullptr80
);
20261
4.75k
    DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
20262
    // Build var to save initial value.
20263
4.75k
    VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
20264
4.75k
    Expr *InitExpr;
20265
4.75k
    DeclRefExpr *Ref = nullptr;
20266
4.75k
    if (!VD && 
!CurContext->isDependentContext()80
) {
20267
80
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20268
80
      if (!isOpenMPCapturedDecl(D)) {
20269
68
        ExprCaptures.push_back(Ref->getDecl());
20270
68
        if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20271
32
          ExprResult RefRes = DefaultLvalueConversion(Ref);
20272
32
          if (!RefRes.isUsable())
20273
0
            continue;
20274
32
          ExprResult PostUpdateRes =
20275
32
              BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
20276
32
                         SimpleRefExpr, RefRes.get());
20277
32
          if (!PostUpdateRes.isUsable())
20278
0
            continue;
20279
32
          ExprPostUpdates.push_back(
20280
32
              IgnoredValueConversions(PostUpdateRes.get()).get());
20281
32
        }
20282
68
      }
20283
80
    }
20284
4.75k
    if (LinKind == OMPC_LINEAR_uval)
20285
84
      InitExpr = VD ? 
VD->getInit()82
:
SimpleRefExpr2
;
20286
4.67k
    else
20287
4.67k
      InitExpr = VD ? 
SimpleRefExpr4.59k
:
Ref78
;
20288
4.75k
    AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
20289
4.75k
                         /*DirectInit=*/false);
20290
4.75k
    DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
20291
20292
4.75k
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
20293
4.75k
    Vars.push_back((VD || 
CurContext->isDependentContext()80
)
20294
4.75k
                       ? 
RefExpr->IgnoreParens()4.67k
20295
4.75k
                       : 
Ref80
);
20296
4.75k
    Privates.push_back(PrivateRef);
20297
4.75k
    Inits.push_back(InitRef);
20298
4.75k
  }
20299
20300
5.85k
  if (Vars.empty())
20301
986
    return nullptr;
20302
20303
4.87k
  Expr *StepExpr = Step;
20304
4.87k
  Expr *CalcStepExpr = nullptr;
20305
4.87k
  if (Step && 
!Step->isValueDependent()2.07k
&&
!Step->isTypeDependent()1.86k
&&
20306
4.87k
      
!Step->isInstantiationDependent()1.86k
&&
20307
4.87k
      
!Step->containsUnexpandedParameterPack()1.86k
) {
20308
1.86k
    SourceLocation StepLoc = Step->getBeginLoc();
20309
1.86k
    ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
20310
1.86k
    if (Val.isInvalid())
20311
0
      return nullptr;
20312
1.86k
    StepExpr = Val.get();
20313
20314
    // Build var to save the step value.
20315
1.86k
    VarDecl *SaveVar =
20316
1.86k
        buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
20317
1.86k
    ExprResult SaveRef =
20318
1.86k
        buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
20319
1.86k
    ExprResult CalcStep =
20320
1.86k
        BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
20321
1.86k
    CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
20322
20323
    // Warn about zero linear step (it would be probably better specified as
20324
    // making corresponding variables 'const').
20325
1.86k
    if (std::optional<llvm::APSInt> Result =
20326
1.86k
            StepExpr->getIntegerConstantExpr(Context)) {
20327
924
      if (!Result->isNegative() && 
!Result->isStrictlyPositive()816
)
20328
94
        Diag(StepLoc, diag::warn_omp_linear_step_zero)
20329
94
            << Vars[0] << (Vars.size() > 1);
20330
937
    } else if (CalcStep.isUsable()) {
20331
      // Calculate the step beforehand instead of doing this on each iteration.
20332
      // (This is not used if the number of iterations may be kfold-ed).
20333
937
      CalcStepExpr = CalcStep.get();
20334
937
    }
20335
1.86k
  }
20336
20337
4.87k
  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
20338
4.87k
                                 ColonLoc, StepModifierLoc, EndLoc, Vars,
20339
4.87k
                                 Privates, Inits, StepExpr, CalcStepExpr,
20340
4.87k
                                 buildPreInits(Context, ExprCaptures),
20341
4.87k
                                 buildPostUpdate(*this, ExprPostUpdates));
20342
4.87k
}
20343
20344
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
20345
                                     Expr *NumIterations, Sema &SemaRef,
20346
3.56k
                                     Scope *S, DSAStackTy *Stack) {
20347
  // Walk the vars and build update/final expressions for the CodeGen.
20348
3.56k
  SmallVector<Expr *, 8> Updates;
20349
3.56k
  SmallVector<Expr *, 8> Finals;
20350
3.56k
  SmallVector<Expr *, 8> UsedExprs;
20351
3.56k
  Expr *Step = Clause.getStep();
20352
3.56k
  Expr *CalcStep = Clause.getCalcStep();
20353
  // OpenMP [2.14.3.7, linear clause]
20354
  // If linear-step is not specified it is assumed to be 1.
20355
3.56k
  if (!Step)
20356
1.90k
    Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
20357
1.65k
  else if (CalcStep)
20358
829
    Step = cast<BinaryOperator>(CalcStep)->getLHS();
20359
3.56k
  bool HasErrors = false;
20360
3.56k
  auto CurInit = Clause.inits().begin();
20361
3.56k
  auto CurPrivate = Clause.privates().begin();
20362
3.56k
  OpenMPLinearClauseKind LinKind = Clause.getModifier();
20363
4.17k
  for (Expr *RefExpr : Clause.varlists()) {
20364
4.17k
    SourceLocation ELoc;
20365
4.17k
    SourceRange ERange;
20366
4.17k
    Expr *SimpleRefExpr = RefExpr;
20367
4.17k
    auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20368
4.17k
    ValueDecl *D = Res.first;
20369
4.17k
    if (Res.second || !D) {
20370
0
      Updates.push_back(nullptr);
20371
0
      Finals.push_back(nullptr);
20372
0
      HasErrors = true;
20373
0
      continue;
20374
0
    }
20375
4.17k
    auto &&Info = Stack->isLoopControlVariable(D);
20376
    // OpenMP [2.15.11, distribute simd Construct]
20377
    // A list item may not appear in a linear clause, unless it is the loop
20378
    // iteration variable.
20379
4.17k
    if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
20380
4.17k
        
isOpenMPSimdDirective(Stack->getCurrentDirective())798
&&
!Info.first798
) {
20381
520
      SemaRef.Diag(ELoc,
20382
520
                   diag::err_omp_linear_distribute_var_non_loop_iteration);
20383
520
      Updates.push_back(nullptr);
20384
520
      Finals.push_back(nullptr);
20385
520
      HasErrors = true;
20386
520
      continue;
20387
520
    }
20388
3.65k
    Expr *InitExpr = *CurInit;
20389
20390
    // Build privatized reference to the current linear var.
20391
3.65k
    auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20392
3.65k
    Expr *CapturedRef;
20393
3.65k
    if (LinKind == OMPC_LINEAR_uval)
20394
60
      CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20395
3.59k
    else
20396
3.59k
      CapturedRef =
20397
3.59k
          buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
20398
3.59k
                           DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20399
3.59k
                           /*RefersToCapture=*/true);
20400
20401
    // Build update: Var = InitExpr + IV * Step
20402
3.65k
    ExprResult Update;
20403
3.65k
    if (!Info.first)
20404
3.24k
      Update = buildCounterUpdate(
20405
3.24k
          SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20406
3.24k
          /*Subtract=*/false, /*IsNonRectangularLB=*/false);
20407
406
    else
20408
406
      Update = *CurPrivate;
20409
3.65k
    Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
20410
3.65k
                                         /*DiscardedValue*/ false);
20411
20412
    // Build final: Var = PrivCopy;
20413
3.65k
    ExprResult Final;
20414
3.65k
    if (!Info.first)
20415
3.24k
      Final = SemaRef.BuildBinOp(
20416
3.24k
          S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20417
3.24k
          SemaRef.DefaultLvalueConversion(*CurPrivate).get());
20418
406
    else
20419
406
      Final = *CurPrivate;
20420
3.65k
    Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
20421
3.65k
                                        /*DiscardedValue*/ false);
20422
20423
3.65k
    if (!Update.isUsable() || !Final.isUsable()) {
20424
0
      Updates.push_back(nullptr);
20425
0
      Finals.push_back(nullptr);
20426
0
      UsedExprs.push_back(nullptr);
20427
0
      HasErrors = true;
20428
3.65k
    } else {
20429
3.65k
      Updates.push_back(Update.get());
20430
3.65k
      Finals.push_back(Final.get());
20431
3.65k
      if (!Info.first)
20432
3.24k
        UsedExprs.push_back(SimpleRefExpr);
20433
3.65k
    }
20434
3.65k
    ++CurInit;
20435
3.65k
    ++CurPrivate;
20436
3.65k
  }
20437
3.56k
  if (Expr *S = Clause.getStep())
20438
1.65k
    UsedExprs.push_back(S);
20439
  // Fill the remaining part with the nullptr.
20440
3.56k
  UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
20441
3.56k
  Clause.setUpdates(Updates);
20442
3.56k
  Clause.setFinals(Finals);
20443
3.56k
  Clause.setUsedExprs(UsedExprs);
20444
3.56k
  return HasErrors;
20445
3.56k
}
20446
20447
OMPClause *Sema::ActOnOpenMPAlignedClause(
20448
    ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
20449
2.97k
    SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
20450
2.97k
  SmallVector<Expr *, 8> Vars;
20451
3.44k
  for (Expr *RefExpr : VarList) {
20452
3.44k
    assert(RefExpr && "NULL expr in OpenMP linear clause.");
20453
3.44k
    SourceLocation ELoc;
20454
3.44k
    SourceRange ERange;
20455
3.44k
    Expr *SimpleRefExpr = RefExpr;
20456
3.44k
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20457
3.44k
    if (Res.second) {
20458
      // It will be analyzed later.
20459
466
      Vars.push_back(RefExpr);
20460
466
    }
20461
3.44k
    ValueDecl *D = Res.first;
20462
3.44k
    if (!D)
20463
666
      continue;
20464
20465
2.77k
    QualType QType = D->getType();
20466
2.77k
    auto *VD = dyn_cast<VarDecl>(D);
20467
20468
    // OpenMP  [2.8.1, simd construct, Restrictions]
20469
    // The type of list items appearing in the aligned clause must be
20470
    // array, pointer, reference to array, or reference to pointer.
20471
2.77k
    QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20472
2.77k
    const Type *Ty = QType.getTypePtrOrNull();
20473
2.77k
    if (!Ty || (!Ty->isArrayType() && 
!Ty->isPointerType()2.15k
)) {
20474
426
      Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20475
426
          << QType << getLangOpts().CPlusPlus << ERange;
20476
426
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20477
426
                               VarDecl::DeclarationOnly;
20478
426
      Diag(D->getLocation(),
20479
426
           IsDecl ? 
diag::note_previous_decl34
:
diag::note_defined_here392
)
20480
426
          << D;
20481
426
      continue;
20482
426
    }
20483
20484
    // OpenMP  [2.8.1, simd construct, Restrictions]
20485
    // A list-item cannot appear in more than one aligned clause.
20486
2.34k
    if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
20487
60
      Diag(ELoc, diag::err_omp_used_in_clause_twice)
20488
60
          << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20489
60
      Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20490
60
          << getOpenMPClauseName(OMPC_aligned);
20491
60
      continue;
20492
60
    }
20493
20494
2.28k
    DeclRefExpr *Ref = nullptr;
20495
2.28k
    if (!VD && 
isOpenMPCapturedDecl(D)96
)
20496
10
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20497
2.28k
    Vars.push_back(DefaultFunctionArrayConversion(
20498
2.28k
                       (VD || 
!Ref96
) ?
RefExpr->IgnoreParens()2.27k
:
Ref10
)
20499
2.28k
                       .get());
20500
2.28k
  }
20501
20502
  // OpenMP [2.8.1, simd construct, Description]
20503
  // The parameter of the aligned clause, alignment, must be a constant
20504
  // positive integer expression.
20505
  // If no optional parameter is specified, implementation-defined default
20506
  // alignments for SIMD instructions on the target platforms are assumed.
20507
2.97k
  if (Alignment != nullptr) {
20508
1.40k
    ExprResult AlignResult =
20509
1.40k
        VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
20510
1.40k
    if (AlignResult.isInvalid())
20511
238
      return nullptr;
20512
1.16k
    Alignment = AlignResult.get();
20513
1.16k
  }
20514
2.73k
  if (Vars.empty())
20515
468
    return nullptr;
20516
20517
2.27k
  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20518
2.27k
                                  EndLoc, Vars, Alignment);
20519
2.73k
}
20520
20521
OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
20522
                                         SourceLocation StartLoc,
20523
                                         SourceLocation LParenLoc,
20524
610
                                         SourceLocation EndLoc) {
20525
610
  SmallVector<Expr *, 8> Vars;
20526
610
  SmallVector<Expr *, 8> SrcExprs;
20527
610
  SmallVector<Expr *, 8> DstExprs;
20528
610
  SmallVector<Expr *, 8> AssignmentOps;
20529
791
  for (Expr *RefExpr : VarList) {
20530
791
    assert(RefExpr && "NULL expr in OpenMP copyin clause.");
20531
791
    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20532
      // It will be analyzed later.
20533
24
      Vars.push_back(RefExpr);
20534
24
      SrcExprs.push_back(nullptr);
20535
24
      DstExprs.push_back(nullptr);
20536
24
      AssignmentOps.push_back(nullptr);
20537
24
      continue;
20538
24
    }
20539
20540
767
    SourceLocation ELoc = RefExpr->getExprLoc();
20541
    // OpenMP [2.1, C/C++]
20542
    //  A list item is a variable name.
20543
    // OpenMP  [2.14.4.1, Restrictions, p.1]
20544
    //  A list item that appears in a copyin clause must be threadprivate.
20545
767
    auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20546
767
    if (!DE || 
!isa<VarDecl>(DE->getDecl())723
) {
20547
44
      Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20548
44
          << 0 << RefExpr->getSourceRange();
20549
44
      continue;
20550
44
    }
20551
20552
723
    Decl *D = DE->getDecl();
20553
723
    auto *VD = cast<VarDecl>(D);
20554
20555
723
    QualType Type = VD->getType();
20556
723
    if (Type->isDependentType() || 
Type->isInstantiationDependentType()603
) {
20557
      // It will be analyzed later.
20558
120
      Vars.push_back(DE);
20559
120
      SrcExprs.push_back(nullptr);
20560
120
      DstExprs.push_back(nullptr);
20561
120
      AssignmentOps.push_back(nullptr);
20562
120
      continue;
20563
120
    }
20564
20565
    // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
20566
    //  A list item that appears in a copyin clause must be threadprivate.
20567
603
    if (!DSAStack->isThreadPrivate(VD)) {
20568
44
      Diag(ELoc, diag::err_omp_required_access)
20569
44
          << getOpenMPClauseName(OMPC_copyin)
20570
44
          << getOpenMPDirectiveName(OMPD_threadprivate);
20571
44
      continue;
20572
44
    }
20573
20574
    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20575
    //  A variable of class type (or array thereof) that appears in a
20576
    //  copyin clause requires an accessible, unambiguous copy assignment
20577
    //  operator for the class type.
20578
559
    QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
20579
559
    VarDecl *SrcVD =
20580
559
        buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
20581
559
                     ".copyin.src", VD->hasAttrs() ? 
&VD->getAttrs()558
:
nullptr1
);
20582
559
    DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
20583
559
        *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
20584
559
    VarDecl *DstVD =
20585
559
        buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
20586
559
                     VD->hasAttrs() ? 
&VD->getAttrs()558
:
nullptr1
);
20587
559
    DeclRefExpr *PseudoDstExpr =
20588
559
        buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
20589
    // For arrays generate assignment operation for single element and replace
20590
    // it by the original array element in CodeGen.
20591
559
    ExprResult AssignmentOp =
20592
559
        BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20593
559
                   PseudoSrcExpr);
20594
559
    if (AssignmentOp.isInvalid())
20595
0
      continue;
20596
559
    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
20597
559
                                       /*DiscardedValue*/ false);
20598
559
    if (AssignmentOp.isInvalid())
20599
0
      continue;
20600
20601
559
    DSAStack->addDSA(VD, DE, OMPC_copyin);
20602
559
    Vars.push_back(DE);
20603
559
    SrcExprs.push_back(PseudoSrcExpr);
20604
559
    DstExprs.push_back(PseudoDstExpr);
20605
559
    AssignmentOps.push_back(AssignmentOp.get());
20606
559
  }
20607
20608
610
  if (Vars.empty())
20609
68
    return nullptr;
20610
20611
542
  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
20612
542
                                 SrcExprs, DstExprs, AssignmentOps);
20613
610
}
20614
20615
OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
20616
                                              SourceLocation StartLoc,
20617
                                              SourceLocation LParenLoc,
20618
190
                                              SourceLocation EndLoc) {
20619
190
  SmallVector<Expr *, 8> Vars;
20620
190
  SmallVector<Expr *, 8> SrcExprs;
20621
190
  SmallVector<Expr *, 8> DstExprs;
20622
190
  SmallVector<Expr *, 8> AssignmentOps;
20623
270
  for (Expr *RefExpr : VarList) {
20624
270
    assert(RefExpr && "NULL expr in OpenMP linear clause.");
20625
270
    SourceLocation ELoc;
20626
270
    SourceRange ERange;
20627
270
    Expr *SimpleRefExpr = RefExpr;
20628
270
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20629
270
    if (Res.second) {
20630
      // It will be analyzed later.
20631
46
      Vars.push_back(RefExpr);
20632
46
      SrcExprs.push_back(nullptr);
20633
46
      DstExprs.push_back(nullptr);
20634
46
      AssignmentOps.push_back(nullptr);
20635
46
    }
20636
270
    ValueDecl *D = Res.first;
20637
270
    if (!D)
20638
54
      continue;
20639
20640
216
    QualType Type = D->getType();
20641
216
    auto *VD = dyn_cast<VarDecl>(D);
20642
20643
    // OpenMP [2.14.4.2, Restrictions, p.2]
20644
    //  A list item that appears in a copyprivate clause may not appear in a
20645
    //  private or firstprivate clause on the single construct.
20646
216
    if (!VD || 
!132
DSAStack132
->isThreadPrivate(VD)) {
20647
174
      DSAStackTy::DSAVarData DVar =
20648
174
          DSAStack->getTopDSA(D, /*FromParent=*/false);
20649
174
      if (DVar.CKind != OMPC_unknown && 
DVar.CKind != OMPC_copyprivate8
&&
20650
174
          
DVar.RefExpr8
) {
20651
8
        Diag(ELoc, diag::err_omp_wrong_dsa)
20652
8
            << getOpenMPClauseName(DVar.CKind)
20653
8
            << getOpenMPClauseName(OMPC_copyprivate);
20654
8
        reportOriginalDsa(*this, DSAStack, D, DVar);
20655
8
        continue;
20656
8
      }
20657
20658
      // OpenMP [2.11.4.2, Restrictions, p.1]
20659
      //  All list items that appear in a copyprivate clause must be either
20660
      //  threadprivate or private in the enclosing context.
20661
166
      if (DVar.CKind == OMPC_unknown) {
20662
166
        DVar = DSAStack->getImplicitDSA(D, false);
20663
166
        if (DVar.CKind == OMPC_shared) {
20664
16
          Diag(ELoc, diag::err_omp_required_access)
20665
16
              << getOpenMPClauseName(OMPC_copyprivate)
20666
16
              << "threadprivate or private in the enclosing context";
20667
16
          reportOriginalDsa(*this, DSAStack, D, DVar);
20668
16
          continue;
20669
16
        }
20670
166
      }
20671
166
    }
20672
20673
    // Variably modified types are not supported.
20674
192
    if (!Type->isAnyPointerType() && 
Type->isVariablyModifiedType()184
) {
20675
0
      Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20676
0
          << getOpenMPClauseName(OMPC_copyprivate) << Type
20677
0
          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20678
0
      bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20679
0
                               VarDecl::DeclarationOnly;
20680
0
      Diag(D->getLocation(),
20681
0
           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20682
0
          << D;
20683
0
      continue;
20684
0
    }
20685
20686
    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20687
    //  A variable of class type (or array thereof) that appears in a
20688
    //  copyin clause requires an accessible, unambiguous copy assignment
20689
    //  operator for the class type.
20690
192
    Type = Context.getBaseElementType(Type.getNonReferenceType())
20691
192
               .getUnqualifiedType();
20692
192
    VarDecl *SrcVD =
20693
192
        buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
20694
192
                     D->hasAttrs() ? 
&D->getAttrs()42
:
nullptr150
);
20695
192
    DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
20696
192
    VarDecl *DstVD =
20697
192
        buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
20698
192
                     D->hasAttrs() ? 
&D->getAttrs()42
:
nullptr150
);
20699
192
    DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
20700
192
    ExprResult AssignmentOp = BuildBinOp(
20701
192
        DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20702
192
    if (AssignmentOp.isInvalid())
20703
0
      continue;
20704
192
    AssignmentOp =
20705
192
        ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
20706
192
    if (AssignmentOp.isInvalid())
20707
0
      continue;
20708
20709
    // No need to mark vars as copyprivate, they are already threadprivate or
20710
    // implicitly private.
20711
192
    assert(VD || isOpenMPCapturedDecl(D));
20712
192
    Vars.push_back(
20713
192
        VD ? 
RefExpr->IgnoreParens()108
20714
192
           : 
buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)84
);
20715
192
    SrcExprs.push_back(PseudoSrcExpr);
20716
192
    DstExprs.push_back(PseudoDstExpr);
20717
192
    AssignmentOps.push_back(AssignmentOp.get());
20718
192
  }
20719
20720
190
  if (Vars.empty())
20721
32
    return nullptr;
20722
20723
158
  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20724
158
                                      Vars, SrcExprs, DstExprs, AssignmentOps);
20725
190
}
20726
20727
OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
20728
                                        SourceLocation StartLoc,
20729
                                        SourceLocation LParenLoc,
20730
86
                                        SourceLocation EndLoc) {
20731
86
  if (VarList.empty())
20732
0
    return nullptr;
20733
20734
86
  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
20735
86
}
20736
20737
/// Tries to find omp_depend_t. type.
20738
static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
20739
5.95k
                           bool Diagnose = true) {
20740
5.95k
  QualType OMPDependT = Stack->getOMPDependT();
20741
5.95k
  if (!OMPDependT.isNull())
20742
1.17k
    return true;
20743
4.78k
  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
20744
4.78k
  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20745
4.78k
  if (!PT.getAsOpaquePtr() || 
PT.get().isNull()32
) {
20746
4.74k
    if (Diagnose)
20747
6
      S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
20748
4.74k
    return false;
20749
4.74k
  }
20750
32
  Stack->setOMPDependT(PT.get());
20751
32
  return true;
20752
4.78k
}
20753
20754
OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
20755
                                         SourceLocation LParenLoc,
20756
576
                                         SourceLocation EndLoc) {
20757
576
  if (!Depobj)
20758
0
    return nullptr;
20759
20760
576
  bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
20761
20762
  // OpenMP 5.0, 2.17.10.1 depobj Construct
20763
  // depobj is an lvalue expression of type omp_depend_t.
20764
576
  if (!Depobj->isTypeDependent() && 
!Depobj->isValueDependent()524
&&
20765
576
      
!Depobj->isInstantiationDependent()524
&&
20766
576
      
!Depobj->containsUnexpandedParameterPack()524
&&
20767
576
      
(524
OMPDependTFound524
&&
20768
524
       
!Context.typesAreCompatible(518
DSAStack518
->getOMPDependT(), Depobj->getType(),
20769
518
                                   /*CompareUnqualified=*/true))) {
20770
48
    Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20771
48
        << 0 << Depobj->getType() << Depobj->getSourceRange();
20772
48
  }
20773
20774
576
  if (!Depobj->isLValue()) {
20775
6
    Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20776
6
        << 1 << Depobj->getSourceRange();
20777
6
  }
20778
20779
576
  return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
20780
576
}
20781
20782
namespace {
20783
// Utility struct that gathers the related info for doacross clause.
20784
struct DoacrossDataInfoTy {
20785
  // The list of expressions.
20786
  SmallVector<Expr *, 8> Vars;
20787
  // The OperatorOffset for doacross loop.
20788
  DSAStackTy::OperatorOffsetTy OpsOffs;
20789
  // The depended loop count.
20790
  llvm::APSInt TotalDepCount;
20791
};
20792
} // namespace
20793
static DoacrossDataInfoTy
20794
ProcessOpenMPDoacrossClauseCommon(Sema &SemaRef, bool IsSource,
20795
                                  ArrayRef<Expr *> VarList, DSAStackTy *Stack,
20796
660
                                  SourceLocation EndLoc) {
20797
20798
660
  SmallVector<Expr *, 8> Vars;
20799
660
  DSAStackTy::OperatorOffsetTy OpsOffs;
20800
660
  llvm::APSInt DepCounter(/*BitWidth=*/32);
20801
660
  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20802
20803
660
  if (const Expr *OrderedCountExpr =
20804
660
          Stack->getParentOrderedRegionParam().first) {
20805
603
    TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.Context);
20806
603
    TotalDepCount.setIsUnsigned(/*Val=*/true);
20807
603
  }
20808
20809
660
  for (Expr *RefExpr : VarList) {
20810
583
    assert(RefExpr && "NULL expr in OpenMP doacross clause.");
20811
583
    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20812
      // It will be analyzed later.
20813
0
      Vars.push_back(RefExpr);
20814
0
      continue;
20815
0
    }
20816
20817
583
    SourceLocation ELoc = RefExpr->getExprLoc();
20818
583
    Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20819
583
    if (!IsSource) {
20820
583
      if (Stack->getParentOrderedRegionParam().first &&
20821
583
          
DepCounter >= TotalDepCount564
) {
20822
14
        SemaRef.Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20823
14
        continue;
20824
14
      }
20825
569
      ++DepCounter;
20826
      // OpenMP  [2.13.9, Summary]
20827
      // depend(dependence-type : vec), where dependence-type is:
20828
      // 'sink' and where vec is the iteration vector, which has the form:
20829
      //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
20830
      // where n is the value specified by the ordered clause in the loop
20831
      // directive, xi denotes the loop iteration variable of the i-th nested
20832
      // loop associated with the loop directive, and di is a constant
20833
      // non-negative integer.
20834
569
      if (SemaRef.CurContext->isDependentContext()) {
20835
        // It will be analyzed later.
20836
197
        Vars.push_back(RefExpr);
20837
197
        continue;
20838
197
      }
20839
372
      SimpleExpr = SimpleExpr->IgnoreImplicit();
20840
372
      OverloadedOperatorKind OOK = OO_None;
20841
372
      SourceLocation OOLoc;
20842
372
      Expr *LHS = SimpleExpr;
20843
372
      Expr *RHS = nullptr;
20844
372
      if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20845
193
        OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
20846
193
        OOLoc = BO->getOperatorLoc();
20847
193
        LHS = BO->getLHS()->IgnoreParenImpCasts();
20848
193
        RHS = BO->getRHS()->IgnoreParenImpCasts();
20849
193
      } else 
if (auto *179
OCE179
= dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20850
0
        OOK = OCE->getOperator();
20851
0
        OOLoc = OCE->getOperatorLoc();
20852
0
        LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20853
0
        RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
20854
179
      } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20855
0
        OOK = MCE->getMethodDecl()
20856
0
                  ->getNameInfo()
20857
0
                  .getName()
20858
0
                  .getCXXOverloadedOperator();
20859
0
        OOLoc = MCE->getCallee()->getExprLoc();
20860
0
        LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
20861
0
        RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20862
0
      }
20863
372
      SourceLocation ELoc;
20864
372
      SourceRange ERange;
20865
372
      auto Res = getPrivateItem(SemaRef, LHS, ELoc, ERange);
20866
372
      if (Res.second) {
20867
        // It will be analyzed later.
20868
0
        Vars.push_back(RefExpr);
20869
0
      }
20870
372
      ValueDecl *D = Res.first;
20871
372
      if (!D)
20872
0
        continue;
20873
20874
372
      if (OOK != OO_Plus && 
OOK != OO_Minus310
&&
(207
RHS207
||
OOK != OO_None179
)) {
20875
28
        SemaRef.Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20876
28
        continue;
20877
28
      }
20878
344
      if (RHS) {
20879
165
        ExprResult RHSRes = SemaRef.VerifyPositiveIntegerConstantInClause(
20880
165
            RHS, OMPC_depend, /*StrictlyPositive=*/false);
20881
165
        if (RHSRes.isInvalid())
20882
14
          continue;
20883
165
      }
20884
330
      if (!SemaRef.CurContext->isDependentContext() &&
20885
330
          Stack->getParentOrderedRegionParam().first &&
20886
330
          
DepCounter != Stack->isParentLoopControlVariable(D).first324
) {
20887
35
        const ValueDecl *VD =
20888
35
            Stack->getParentLoopControlVariable(DepCounter.getZExtValue());
20889
35
        if (VD)
20890
28
          SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20891
28
              << 1 << VD;
20892
7
        else
20893
7
          SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20894
7
              << 0;
20895
35
        continue;
20896
35
      }
20897
295
      OpsOffs.emplace_back(RHS, OOK);
20898
295
    }
20899
295
    Vars.push_back(RefExpr->IgnoreParenImpCasts());
20900
295
  }
20901
660
  if (!SemaRef.CurContext->isDependentContext() && 
!IsSource428
&&
20902
660
      
TotalDepCount > VarList.size()255
&&
20903
660
      
Stack->getParentOrderedRegionParam().first63
&&
20904
660
      
Stack->getParentLoopControlVariable(VarList.size() + 1)63
) {
20905
56
    SemaRef.Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
20906
56
        << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1);
20907
56
  }
20908
660
  return {Vars, OpsOffs, TotalDepCount};
20909
660
}
20910
20911
OMPClause *
20912
Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data,
20913
                              Expr *DepModifier, ArrayRef<Expr *> VarList,
20914
                              SourceLocation StartLoc, SourceLocation LParenLoc,
20915
6.99k
                              SourceLocation EndLoc) {
20916
6.99k
  OpenMPDependClauseKind DepKind = Data.DepKind;
20917
6.99k
  SourceLocation DepLoc = Data.DepLoc;
20918
6.99k
  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
20919
6.99k
      
DepKind != OMPC_DEPEND_source565
&&
DepKind != OMPC_DEPEND_sink354
) {
20920
24
    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20921
24
        << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20922
24
    return nullptr;
20923
24
  }
20924
6.96k
  if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
20925
6.96k
      
DepKind == OMPC_DEPEND_mutexinoutset200
) {
20926
4
    Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
20927
4
    return nullptr;
20928
4
  }
20929
6.96k
  if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
20930
6.96k
       
DSAStack541
->getCurrentDirective() == OMPD_depobj541
) &&
20931
6.96k
      
(6.42k
DepKind == OMPC_DEPEND_unknown6.42k
||
DepKind == OMPC_DEPEND_source6.06k
||
20932
6.42k
       
DepKind == OMPC_DEPEND_sink5.84k
||
20933
6.42k
       
(5.84k
(5.84k
LangOpts.OpenMP < 505.84k
||
20934
5.84k
         
DSAStack4.20k
->getCurrentDirective() == OMPD_depobj4.20k
) &&
20935
5.84k
        
DepKind == OMPC_DEPEND_depobj1.99k
))) {
20936
581
    SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
20937
581
                                       OMPC_DEPEND_outallmemory,
20938
581
                                       OMPC_DEPEND_inoutallmemory};
20939
581
    if (LangOpts.OpenMP < 50 || 
DSAStack385
->getCurrentDirective() == OMPD_depobj385
)
20940
202
      Except.push_back(OMPC_DEPEND_depobj);
20941
581
    if (LangOpts.OpenMP < 51)
20942
390
      Except.push_back(OMPC_DEPEND_inoutset);
20943
581
    std::string Expected = (LangOpts.OpenMP >= 50 && 
!DepModifier385
)
20944
581
                               ? 
"depend modifier(iterator) or "381
20945
581
                               : 
""200
;
20946
581
    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20947
581
        << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
20948
581
                                              /*Last=*/OMPC_DEPEND_unknown,
20949
581
                                              Except)
20950
581
        << getOpenMPClauseName(OMPC_depend);
20951
581
    return nullptr;
20952
581
  }
20953
6.38k
  if (DepModifier &&
20954
6.38k
      
(45
DepKind == OMPC_DEPEND_source45
||
DepKind == OMPC_DEPEND_sink45
)) {
20955
0
    Diag(DepModifier->getExprLoc(),
20956
0
         diag::err_omp_depend_sink_source_with_modifier);
20957
0
    return nullptr;
20958
0
  }
20959
6.38k
  if (DepModifier &&
20960
6.38k
      
!DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)45
)
20961
0
    Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
20962
20963
6.38k
  SmallVector<Expr *, 8> Vars;
20964
6.38k
  DSAStackTy::OperatorOffsetTy OpsOffs;
20965
6.38k
  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20966
20967
6.38k
  if (DepKind == OMPC_DEPEND_sink || 
DepKind == OMPC_DEPEND_source6.05k
) {
20968
541
    DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
20969
541
        *this, DepKind == OMPC_DEPEND_source, VarList, DSAStack, EndLoc);
20970
541
    Vars = VarOffset.Vars;
20971
541
    OpsOffs = VarOffset.OpsOffs;
20972
541
    TotalDepCount = VarOffset.TotalDepCount;
20973
5.84k
  } else {
20974
7.42k
    for (Expr *RefExpr : VarList) {
20975
7.42k
      assert(RefExpr && "NULL expr in OpenMP shared clause.");
20976
7.42k
      if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20977
        // It will be analyzed later.
20978
0
        Vars.push_back(RefExpr);
20979
0
        continue;
20980
0
      }
20981
20982
7.42k
      SourceLocation ELoc = RefExpr->getExprLoc();
20983
7.42k
      Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20984
7.42k
      if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
20985
7.42k
        bool OMPDependTFound = LangOpts.OpenMP >= 50;
20986
7.42k
        if (OMPDependTFound)
20987
5.37k
          OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
20988
5.37k
                                           DepKind == OMPC_DEPEND_depobj);
20989
7.42k
        if (DepKind == OMPC_DEPEND_depobj) {
20990
          // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20991
          // List items used in depend clauses with the depobj dependence type
20992
          // must be expressions of the omp_depend_t type.
20993
44
          if (!RefExpr->isValueDependent() && 
!RefExpr->isTypeDependent()40
&&
20994
44
              
!RefExpr->isInstantiationDependent()40
&&
20995
44
              
!RefExpr->containsUnexpandedParameterPack()40
&&
20996
44
              
(40
OMPDependTFound40
&&
20997
40
               !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
20998
40
                                               RefExpr->getType()))) {
20999
8
            Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21000
8
                << 0 << RefExpr->getType() << RefExpr->getSourceRange();
21001
8
            continue;
21002
8
          }
21003
36
          if (!RefExpr->isLValue()) {
21004
0
            Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21005
0
                << 1 << RefExpr->getType() << RefExpr->getSourceRange();
21006
0
            continue;
21007
0
          }
21008
7.38k
        } else {
21009
          // OpenMP 5.0 [2.17.11, Restrictions]
21010
          // List items used in depend clauses cannot be zero-length array
21011
          // sections.
21012
7.38k
          QualType ExprTy = RefExpr->getType().getNonReferenceType();
21013
7.38k
          const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
21014
7.38k
          if (OASE) {
21015
2.24k
            QualType BaseType =
21016
2.24k
                OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
21017
2.24k
            if (BaseType.isNull())
21018
1
              return nullptr;
21019
2.24k
            if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21020
1.03k
              ExprTy = ATy->getElementType();
21021
1.20k
            else
21022
1.20k
              ExprTy = BaseType->getPointeeType();
21023
2.24k
            ExprTy = ExprTy.getNonReferenceType();
21024
2.24k
            const Expr *Length = OASE->getLength();
21025
2.24k
            Expr::EvalResult Result;
21026
2.24k
            if (Length && 
!Length->isValueDependent()1.26k
&&
21027
2.24k
                
Length->EvaluateAsInt(Result, Context)1.00k
&&
21028
2.24k
                
Result.Val.getInt().isZero()165
) {
21029
105
              Diag(ELoc,
21030
105
                   diag::err_omp_depend_zero_length_array_section_not_allowed)
21031
105
                  << SimpleExpr->getSourceRange();
21032
105
              continue;
21033
105
            }
21034
2.24k
          }
21035
21036
          // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
21037
          // List items used in depend clauses with the in, out, inout,
21038
          // inoutset, or mutexinoutset dependence types cannot be
21039
          // expressions of the omp_depend_t type.
21040
7.27k
          if (!RefExpr->isValueDependent() && 
!RefExpr->isTypeDependent()6.22k
&&
21041
7.27k
              
!RefExpr->isInstantiationDependent()6.22k
&&
21042
7.27k
              
!RefExpr->containsUnexpandedParameterPack()6.22k
&&
21043
7.27k
              
(6.22k
!RefExpr->IgnoreParenImpCasts()->isLValue()6.22k
||
21044
6.22k
               
(6.01k
OMPDependTFound6.01k
&&
DSAStack538
->getOMPDependT().getTypePtr() ==
21045
538
                                       ExprTy.getTypePtr()))) {
21046
210
            Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21047
210
                << (LangOpts.OpenMP >= 50 ? 
1144
:
066
)
21048
210
                << (LangOpts.OpenMP >= 50 ? 
1144
:
066
) << RefExpr->getSourceRange();
21049
210
            continue;
21050
210
          }
21051
21052
7.06k
          auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
21053
7.06k
          if (ASE && 
!ASE->getBase()->isTypeDependent()704
&&
21054
7.06k
              !ASE->getBase()
21055
593
                   ->getType()
21056
593
                   .getNonReferenceType()
21057
593
                   ->isPointerType() &&
21058
7.06k
              
!ASE->getBase()->getType().getNonReferenceType()->isArrayType()105
) {
21059
105
            Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21060
105
                << (LangOpts.OpenMP >= 50 ? 
171
:
034
)
21061
105
                << (LangOpts.OpenMP >= 50 ? 
171
:
034
) << RefExpr->getSourceRange();
21062
105
            continue;
21063
105
          }
21064
21065
6.96k
          ExprResult Res;
21066
6.96k
          {
21067
6.96k
            Sema::TentativeAnalysisScope Trap(*this);
21068
6.96k
            Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
21069
6.96k
                                       RefExpr->IgnoreParenImpCasts());
21070
6.96k
          }
21071
6.96k
          if (!Res.isUsable() && 
!isa<OMPArraySectionExpr>(SimpleExpr)1.59k
&&
21072
6.96k
              
!isa<OMPArrayShapingExpr>(SimpleExpr)40
) {
21073
0
            Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21074
0
                << (LangOpts.OpenMP >= 50 ? 1 : 0)
21075
0
                << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21076
0
            continue;
21077
0
          }
21078
6.96k
        }
21079
7.42k
      }
21080
6.99k
      Vars.push_back(RefExpr->IgnoreParenImpCasts());
21081
6.99k
    }
21082
5.84k
  }
21083
21084
6.38k
  if (DepKind != OMPC_DEPEND_source && 
DepKind != OMPC_DEPEND_sink6.17k
&&
21085
6.38k
      
DepKind != OMPC_DEPEND_outallmemory5.84k
&&
21086
6.38k
      
DepKind != OMPC_DEPEND_inoutallmemory5.82k
&&
Vars.empty()5.80k
)
21087
1.94k
    return nullptr;
21088
21089
4.43k
  auto *C = OMPDependClause::Create(
21090
4.43k
      Context, StartLoc, LParenLoc, EndLoc,
21091
4.43k
      {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars,
21092
4.43k
      TotalDepCount.getZExtValue());
21093
4.43k
  if ((DepKind == OMPC_DEPEND_sink || 
DepKind == OMPC_DEPEND_source4.10k
) &&
21094
4.43k
      
DSAStack541
->isParentOrderedRegion()541
)
21095
512
    DSAStack->addDoacrossDependClause(C, OpsOffs);
21096
4.43k
  return C;
21097
6.38k
}
21098
21099
OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
21100
                                         Expr *Device, SourceLocation StartLoc,
21101
                                         SourceLocation LParenLoc,
21102
                                         SourceLocation ModifierLoc,
21103
1.40k
                                         SourceLocation EndLoc) {
21104
1.40k
  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
21105
1.40k
         "Unexpected device modifier in OpenMP < 50.");
21106
21107
1.40k
  bool ErrorFound = false;
21108
1.40k
  if (ModifierLoc.isValid() && 
Modifier == OMPC_DEVICE_unknown54
) {
21109
2
    std::string Values =
21110
2
        getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
21111
2
    Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
21112
2
        << Values << getOpenMPClauseName(OMPC_device);
21113
2
    ErrorFound = true;
21114
2
  }
21115
21116
1.40k
  Expr *ValExpr = Device;
21117
1.40k
  Stmt *HelperValStmt = nullptr;
21118
21119
  // OpenMP [2.9.1, Restrictions]
21120
  // The device expression must evaluate to a non-negative integer value.
21121
1.40k
  ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
21122
1.40k
                                          /*StrictlyPositive=*/false) ||
21123
1.40k
               
ErrorFound1.37k
;
21124
1.40k
  if (ErrorFound)
21125
35
    return nullptr;
21126
21127
  // OpenMP 5.0 [2.12.5, Restrictions]
21128
  // In case of ancestor device-modifier, a requires directive with
21129
  // the reverse_offload clause must be specified.
21130
1.37k
  if (Modifier == OMPC_DEVICE_ancestor) {
21131
18
    if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
21132
6
      targetDiag(
21133
6
          StartLoc,
21134
6
          diag::err_omp_device_ancestor_without_requires_reverse_offload);
21135
6
      ErrorFound = true;
21136
6
    }
21137
18
  }
21138
21139
1.37k
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
21140
1.37k
  OpenMPDirectiveKind CaptureRegion =
21141
1.37k
      getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
21142
1.37k
  if (CaptureRegion != OMPD_unknown && 
!CurContext->isDependentContext()1.28k
) {
21143
1.17k
    ValExpr = MakeFullExpr(ValExpr).get();
21144
1.17k
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21145
1.17k
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21146
1.17k
    HelperValStmt = buildPreInits(Context, Captures);
21147
1.17k
  }
21148
21149
1.37k
  return new (Context)
21150
1.37k
      OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
21151
1.37k
                      LParenLoc, ModifierLoc, EndLoc);
21152
1.40k
}
21153
21154
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
21155
                              DSAStackTy *Stack, QualType QTy,
21156
62.8k
                              bool FullCheck = true) {
21157
62.8k
  if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
21158
772
    return false;
21159
62.0k
  if (FullCheck && 
!SemaRef.CurContext->isDependentContext()57.2k
&&
21160
62.0k
      
!QTy.isTriviallyCopyableType(SemaRef.Context)55.0k
)
21161
8.90k
    SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
21162
62.0k
  return true;
21163
62.8k
}
21164
21165
/// Return true if it can be proven that the provided array expression
21166
/// (array section or array subscript) does NOT specify the whole size of the
21167
/// array whose base type is \a BaseQTy.
21168
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
21169
                                                        const Expr *E,
21170
13.0k
                                                        QualType BaseQTy) {
21171
13.0k
  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21172
21173
  // If this is an array subscript, it refers to the whole size if the size of
21174
  // the dimension is constant and equals 1. Also, an array section assumes the
21175
  // format of an array subscript if no colon is used.
21176
13.0k
  if (isa<ArraySubscriptExpr>(E) ||
21177
13.0k
      
(10.9k
OASE10.9k
&&
OASE->getColonLocFirst().isInvalid()10.9k
)) {
21178
2.25k
    if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
21179
1.31k
      return ATy->getSize().getSExtValue() != 1;
21180
    // Size can't be evaluated statically.
21181
939
    return false;
21182
2.25k
  }
21183
21184
10.7k
  assert(OASE && "Expecting array section if not an array subscript.");
21185
10.7k
  const Expr *LowerBound = OASE->getLowerBound();
21186
10.7k
  const Expr *Length = OASE->getLength();
21187
21188
  // If there is a lower bound that does not evaluates to zero, we are not
21189
  // covering the whole dimension.
21190
10.7k
  if (LowerBound) {
21191
3.77k
    Expr::EvalResult Result;
21192
3.77k
    if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
21193
276
      return false; // Can't get the integer value as a constant.
21194
21195
3.49k
    llvm::APSInt ConstLowerBound = Result.Val.getInt();
21196
3.49k
    if (ConstLowerBound.getSExtValue())
21197
1.55k
      return true;
21198
3.49k
  }
21199
21200
  // If we don't have a length we covering the whole dimension.
21201
8.91k
  if (!Length)
21202
1.56k
    return false;
21203
21204
  // If the base is a pointer, we don't have a way to get the size of the
21205
  // pointee.
21206
7.34k
  if (BaseQTy->isPointerType())
21207
2.26k
    return false;
21208
21209
  // We can only check if the length is the same as the size of the dimension
21210
  // if we have a constant array.
21211
5.08k
  const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
21212
5.08k
  if (!CATy)
21213
436
    return false;
21214
21215
4.64k
  Expr::EvalResult Result;
21216
4.64k
  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21217
432
    return false; // Can't get the integer value as a constant.
21218
21219
4.21k
  llvm::APSInt ConstLength = Result.Val.getInt();
21220
4.21k
  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
21221
4.64k
}
21222
21223
// Return true if it can be proven that the provided array expression (array
21224
// section or array subscript) does NOT specify a single element of the array
21225
// whose base type is \a BaseQTy.
21226
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
21227
                                                        const Expr *E,
21228
10.8k
                                                        QualType BaseQTy) {
21229
10.8k
  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21230
21231
  // An array subscript always refer to a single element. Also, an array section
21232
  // assumes the format of an array subscript if no colon is used.
21233
10.8k
  if (isa<ArraySubscriptExpr>(E) ||
21234
10.8k
      (OASE && OASE->getColonLocFirst().isInvalid()))
21235
235
    return false;
21236
21237
10.6k
  assert(OASE && "Expecting array section if not an array subscript.");
21238
10.6k
  const Expr *Length = OASE->getLength();
21239
21240
  // If we don't have a length we have to check if the array has unitary size
21241
  // for this dimension. Also, we should always expect a length if the base type
21242
  // is pointer.
21243
10.6k
  if (!Length) {
21244
1.84k
    if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
21245
1.65k
      return ATy->getSize().getSExtValue() != 1;
21246
    // We cannot assume anything.
21247
184
    return false;
21248
1.84k
  }
21249
21250
  // Check if the length evaluates to 1.
21251
8.79k
  Expr::EvalResult Result;
21252
8.79k
  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21253
829
    return false; // Can't get the integer value as a constant.
21254
21255
7.96k
  llvm::APSInt ConstLength = Result.Val.getInt();
21256
7.96k
  return ConstLength.getSExtValue() != 1;
21257
8.79k
}
21258
21259
// The base of elements of list in a map clause have to be either:
21260
//  - a reference to variable or field.
21261
//  - a member expression.
21262
//  - an array expression.
21263
//
21264
// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
21265
// reference to 'r'.
21266
//
21267
// If we have:
21268
//
21269
// struct SS {
21270
//   Bla S;
21271
//   foo() {
21272
//     #pragma omp target map (S.Arr[:12]);
21273
//   }
21274
// }
21275
//
21276
// We want to retrieve the member expression 'this->S';
21277
21278
// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
21279
//  If a list item is an array section, it must specify contiguous storage.
21280
//
21281
// For this restriction it is sufficient that we make sure only references
21282
// to variables or fields and array expressions, and that no array sections
21283
// exist except in the rightmost expression (unless they cover the whole
21284
// dimension of the array). E.g. these would be invalid:
21285
//
21286
//   r.ArrS[3:5].Arr[6:7]
21287
//
21288
//   r.ArrS[3:5].x
21289
//
21290
// but these would be valid:
21291
//   r.ArrS[3].Arr[6:7]
21292
//
21293
//   r.ArrS[3].x
21294
namespace {
21295
class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
21296
  Sema &SemaRef;
21297
  OpenMPClauseKind CKind = OMPC_unknown;
21298
  OpenMPDirectiveKind DKind = OMPD_unknown;
21299
  OMPClauseMappableExprCommon::MappableExprComponentList &Components;
21300
  bool IsNonContiguous = false;
21301
  bool NoDiagnose = false;
21302
  const Expr *RelevantExpr = nullptr;
21303
  bool AllowUnitySizeArraySection = true;
21304
  bool AllowWholeSizeArraySection = true;
21305
  bool AllowAnotherPtr = true;
21306
  SourceLocation ELoc;
21307
  SourceRange ERange;
21308
21309
544
  void emitErrorMsg() {
21310
    // If nothing else worked, this is not a valid map clause expression.
21311
544
    if (SemaRef.getLangOpts().OpenMP < 50) {
21312
318
      SemaRef.Diag(ELoc,
21313
318
                   diag::err_omp_expected_named_var_member_or_array_expression)
21314
318
          << ERange;
21315
318
    } else {
21316
226
      SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21317
226
          << getOpenMPClauseName(CKind) << ERange;
21318
226
    }
21319
544
  }
21320
21321
public:
21322
58.4k
  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
21323
58.4k
    if (!isa<VarDecl>(DRE->getDecl())) {
21324
8
      emitErrorMsg();
21325
8
      return false;
21326
8
    }
21327
58.4k
    assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21328
58.4k
    RelevantExpr = DRE;
21329
    // Record the component.
21330
58.4k
    Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
21331
58.4k
    return true;
21332
58.4k
  }
21333
21334
12.1k
  bool VisitMemberExpr(MemberExpr *ME) {
21335
12.1k
    Expr *E = ME;
21336
12.1k
    Expr *BaseE = ME->getBase()->IgnoreParenCasts();
21337
21338
12.1k
    if (isa<CXXThisExpr>(BaseE)) {
21339
3.83k
      assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21340
      // We found a base expression: this->Val.
21341
3.83k
      RelevantExpr = ME;
21342
8.32k
    } else {
21343
8.32k
      E = BaseE;
21344
8.32k
    }
21345
21346
12.1k
    if (!isa<FieldDecl>(ME->getMemberDecl())) {
21347
0
      if (!NoDiagnose) {
21348
0
        SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
21349
0
            << ME->getSourceRange();
21350
0
        return false;
21351
0
      }
21352
0
      if (RelevantExpr)
21353
0
        return false;
21354
0
      return Visit(E);
21355
0
    }
21356
21357
12.1k
    auto *FD = cast<FieldDecl>(ME->getMemberDecl());
21358
21359
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
21360
    //  A bit-field cannot appear in a map clause.
21361
    //
21362
12.1k
    if (FD->isBitField()) {
21363
50
      if (!NoDiagnose) {
21364
50
        SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
21365
50
            << ME->getSourceRange() << getOpenMPClauseName(CKind);
21366
50
        return false;
21367
50
      }
21368
0
      if (RelevantExpr)
21369
0
        return false;
21370
0
      return Visit(E);
21371
0
    }
21372
21373
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21374
    //  If the type of a list item is a reference to a type T then the type
21375
    //  will be considered to be T for all purposes of this clause.
21376
12.1k
    QualType CurType = BaseE->getType().getNonReferenceType();
21377
21378
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
21379
    //  A list item cannot be a variable that is a member of a structure with
21380
    //  a union type.
21381
    //
21382
12.1k
    if (CurType->isUnionType()) {
21383
49
      if (!NoDiagnose) {
21384
28
        SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
21385
28
            << ME->getSourceRange();
21386
28
        return false;
21387
28
      }
21388
21
      return RelevantExpr || Visit(E);
21389
49
    }
21390
21391
    // If we got a member expression, we should not expect any array section
21392
    // before that:
21393
    //
21394
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
21395
    //  If a list item is an element of a structure, only the rightmost symbol
21396
    //  of the variable reference can be an array section.
21397
    //
21398
12.0k
    AllowUnitySizeArraySection = false;
21399
12.0k
    AllowWholeSizeArraySection = false;
21400
21401
    // Record the component.
21402
12.0k
    Components.emplace_back(ME, FD, IsNonContiguous);
21403
12.0k
    return RelevantExpr || 
Visit(E)8.22k
;
21404
12.1k
  }
21405
21406
2.02k
  bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
21407
2.02k
    Expr *E = AE->getBase()->IgnoreParenImpCasts();
21408
21409
2.02k
    if (!E->getType()->isAnyPointerType() && 
!E->getType()->isArrayType()1.33k
) {
21410
0
      if (!NoDiagnose) {
21411
0
        SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21412
0
            << 0 << AE->getSourceRange();
21413
0
        return false;
21414
0
      }
21415
0
      return RelevantExpr || Visit(E);
21416
0
    }
21417
21418
    // If we got an array subscript that express the whole dimension we
21419
    // can have any array expressions before. If it only expressing part of
21420
    // the dimension, we can only have unitary-size array expressions.
21421
2.02k
    if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
21422
1.10k
      AllowWholeSizeArraySection = false;
21423
21424
2.02k
    if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
21425
74
      Expr::EvalResult Result;
21426
74
      if (!AE->getIdx()->isValueDependent() &&
21427
74
          AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
21428
74
          
!Result.Val.getInt().isZero()62
) {
21429
4
        SemaRef.Diag(AE->getIdx()->getExprLoc(),
21430
4
                     diag::err_omp_invalid_map_this_expr);
21431
4
        SemaRef.Diag(AE->getIdx()->getExprLoc(),
21432
4
                     diag::note_omp_invalid_subscript_on_this_ptr_map);
21433
4
      }
21434
74
      assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21435
74
      RelevantExpr = TE;
21436
74
    }
21437
21438
    // Record the component - we don't have any declaration associated.
21439
2.02k
    Components.emplace_back(AE, nullptr, IsNonContiguous);
21440
21441
2.02k
    return RelevantExpr || 
Visit(E)1.94k
;
21442
2.02k
  }
21443
21444
10.8k
  bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
21445
    // After OMP 5.0  Array section in reduction clause will be implicitly
21446
    // mapped
21447
10.8k
    assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
21448
10.8k
           "Array sections cannot be implicitly mapped.");
21449
10.8k
    Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21450
10.8k
    QualType CurType =
21451
10.8k
        OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21452
21453
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21454
    //  If the type of a list item is a reference to a type T then the type
21455
    //  will be considered to be T for all purposes of this clause.
21456
10.8k
    if (CurType->isReferenceType())
21457
0
      CurType = CurType->getPointeeType();
21458
21459
10.8k
    bool IsPointer = CurType->isAnyPointerType();
21460
21461
10.8k
    if (!IsPointer && 
!CurType->isArrayType()7.91k
) {
21462
0
      SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21463
0
          << 0 << OASE->getSourceRange();
21464
0
      return false;
21465
0
    }
21466
21467
10.8k
    bool NotWhole =
21468
10.8k
        checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
21469
10.8k
    bool NotUnity =
21470
10.8k
        checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
21471
21472
10.8k
    if (AllowWholeSizeArraySection) {
21473
      // Any array section is currently allowed. Allowing a whole size array
21474
      // section implies allowing a unity array section as well.
21475
      //
21476
      // If this array section refers to the whole dimension we can still
21477
      // accept other array sections before this one, except if the base is a
21478
      // pointer. Otherwise, only unitary sections are accepted.
21479
9.05k
      if (NotWhole || 
IsPointer5.34k
)
21480
5.67k
        AllowWholeSizeArraySection = false;
21481
9.05k
    } else 
if (1.81k
DKind == OMPD_target_update1.81k
&&
21482
1.81k
               
SemaRef.getLangOpts().OpenMP >= 50764
) {
21483
748
      if (IsPointer && 
!AllowAnotherPtr20
)
21484
20
        SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21485
20
            << /*array of unknown bound */ 1;
21486
728
      else
21487
728
        IsNonContiguous = true;
21488
1.06k
    } else if (AllowUnitySizeArraySection && NotUnity) {
21489
      // A unity or whole array section is not allowed and that is not
21490
      // compatible with the properties of the current array section.
21491
431
      if (NoDiagnose)
21492
13
        return false;
21493
418
      SemaRef.Diag(ELoc,
21494
418
                   diag::err_array_section_does_not_specify_contiguous_storage)
21495
418
          << OASE->getSourceRange();
21496
418
      return false;
21497
431
    }
21498
21499
10.4k
    if (IsPointer)
21500
2.85k
      AllowAnotherPtr = false;
21501
21502
10.4k
    if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21503
44
      Expr::EvalResult ResultR;
21504
44
      Expr::EvalResult ResultL;
21505
44
      if (!OASE->getLength()->isValueDependent() &&
21506
44
          OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
21507
44
          
!ResultR.Val.getInt().isOne()32
) {
21508
4
        SemaRef.Diag(OASE->getLength()->getExprLoc(),
21509
4
                     diag::err_omp_invalid_map_this_expr);
21510
4
        SemaRef.Diag(OASE->getLength()->getExprLoc(),
21511
4
                     diag::note_omp_invalid_length_on_this_ptr_mapping);
21512
4
      }
21513
44
      if (OASE->getLowerBound() && 
!OASE->getLowerBound()->isValueDependent()16
&&
21514
44
          OASE->getLowerBound()->EvaluateAsInt(ResultL,
21515
16
                                               SemaRef.getASTContext()) &&
21516
44
          
!ResultL.Val.getInt().isZero()4
) {
21517
4
        SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21518
4
                     diag::err_omp_invalid_map_this_expr);
21519
4
        SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21520
4
                     diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21521
4
      }
21522
44
      assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21523
44
      RelevantExpr = TE;
21524
44
    }
21525
21526
    // Record the component - we don't have any declaration associated.
21527
10.4k
    Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
21528
10.4k
    return RelevantExpr || 
Visit(E)10.3k
;
21529
10.4k
  }
21530
85
  bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
21531
85
    Expr *Base = E->getBase();
21532
21533
    // Record the component - we don't have any declaration associated.
21534
85
    Components.emplace_back(E, nullptr, IsNonContiguous);
21535
21536
85
    return Visit(Base->IgnoreParenImpCasts());
21537
85
  }
21538
21539
739
  bool VisitUnaryOperator(UnaryOperator *UO) {
21540
739
    if (SemaRef.getLangOpts().OpenMP < 50 || 
!UO->isLValue()569
||
21541
739
        
UO->getOpcode() != UO_Deref569
) {
21542
170
      emitErrorMsg();
21543
170
      return false;
21544
170
    }
21545
569
    if (!RelevantExpr) {
21546
      // Record the component if haven't found base decl.
21547
569
      Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
21548
569
    }
21549
569
    return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
21550
739
  }
21551
555
  bool VisitBinaryOperator(BinaryOperator *BO) {
21552
555
    if (SemaRef.getLangOpts().OpenMP < 50 || 
!BO->getType()->isPointerType()517
) {
21553
38
      emitErrorMsg();
21554
38
      return false;
21555
38
    }
21556
21557
    // Pointer arithmetic is the only thing we expect to happen here so after we
21558
    // make sure the binary operator is a pointer type, the only thing we need
21559
    // to do is to visit the subtree that has the same type as root (so that we
21560
    // know the other subtree is just an offset)
21561
517
    Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
21562
517
    Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
21563
517
    Components.emplace_back(BO, nullptr, false);
21564
517
    assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
21565
517
            RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
21566
517
           "Either LHS or RHS have base decl inside");
21567
517
    if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
21568
303
      return RelevantExpr || Visit(LE);
21569
214
    return RelevantExpr || Visit(RE);
21570
517
  }
21571
5
  bool VisitCXXThisExpr(CXXThisExpr *CTE) {
21572
5
    assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21573
5
    RelevantExpr = CTE;
21574
5
    Components.emplace_back(CTE, nullptr, IsNonContiguous);
21575
5
    return true;
21576
5
  }
21577
42
  bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
21578
42
    assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21579
42
    Components.emplace_back(COCE, nullptr, IsNonContiguous);
21580
42
    return true;
21581
42
  }
21582
16
  bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
21583
16
    Expr *Source = E->getSourceExpr();
21584
16
    if (!Source) {
21585
0
      emitErrorMsg();
21586
0
      return false;
21587
0
    }
21588
16
    return Visit(Source);
21589
16
  }
21590
328
  bool VisitStmt(Stmt *) {
21591
328
    emitErrorMsg();
21592
328
    return false;
21593
328
  }
21594
62.4k
  const Expr *getFoundBase() const { return RelevantExpr; }
21595
  explicit MapBaseChecker(
21596
      Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
21597
      OMPClauseMappableExprCommon::MappableExprComponentList &Components,
21598
      bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
21599
63.4k
      : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21600
63.4k
        NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21601
};
21602
} // namespace
21603
21604
/// Return the expression of the base of the mappable expression or null if it
21605
/// cannot be determined and do all the necessary checks to see if the
21606
/// expression is valid as a standalone mappable expression. In the process,
21607
/// record all the components of the expression.
21608
static const Expr *checkMapClauseExpressionBase(
21609
    Sema &SemaRef, Expr *E,
21610
    OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
21611
63.4k
    OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
21612
63.4k
  SourceLocation ELoc = E->getExprLoc();
21613
63.4k
  SourceRange ERange = E->getSourceRange();
21614
63.4k
  MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21615
63.4k
                         ERange);
21616
63.4k
  if (Checker.Visit(E->IgnoreParens())) {
21617
    // Check if the highest dimension array section has length specified
21618
62.4k
    if (SemaRef.getLangOpts().OpenMP >= 50 && 
!CurComponents.empty()43.9k
&&
21619
62.4k
        
(43.9k
CKind == OMPC_to43.9k
||
CKind == OMPC_from42.2k
)) {
21620
2.79k
      auto CI = CurComponents.rbegin();
21621
2.79k
      auto CE = CurComponents.rend();
21622
6.78k
      for (; CI != CE; 
++CI3.98k
) {
21623
4.71k
        const auto *OASE =
21624
4.71k
            dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21625
4.71k
        if (!OASE)
21626
3.96k
          continue;
21627
748
        if (OASE && OASE->getLength())
21628
728
          break;
21629
20
        SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
21630
20
            << ERange;
21631
20
      }
21632
2.79k
    }
21633
62.4k
    return Checker.getFoundBase();
21634
62.4k
  }
21635
1.05k
  return nullptr;
21636
63.4k
}
21637
21638
// Return true if expression E associated with value VD has conflicts with other
21639
// map information.
21640
static bool checkMapConflicts(
21641
    Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
21642
    bool CurrentRegionOnly,
21643
    OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
21644
99.0k
    OpenMPClauseKind CKind) {
21645
99.0k
  assert(VD && E);
21646
99.0k
  SourceLocation ELoc = E->getExprLoc();
21647
99.0k
  SourceRange ERange = E->getSourceRange();
21648
21649
  // In order to easily check the conflicts we need to match each component of
21650
  // the expression under test with the components of the expressions that are
21651
  // already in the stack.
21652
21653
99.0k
  assert(!CurComponents.empty() && "Map clause expression with no components!");
21654
99.0k
  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21655
99.0k
         "Map clause expression with unexpected base!");
21656
21657
  // Variables to help detecting enclosing problems in data environment nests.
21658
99.0k
  bool IsEnclosedByDataEnvironmentExpr = false;
21659
99.0k
  const Expr *EnclosingExpr = nullptr;
21660
21661
99.0k
  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21662
99.0k
      VD, CurrentRegionOnly,
21663
99.0k
      [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21664
99.0k
       ERange, CKind, &EnclosingExpr,
21665
99.0k
       CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
21666
99.0k
                          StackComponents,
21667
99.0k
                      OpenMPClauseKind Kind) {
21668
5.38k
        if (CKind == Kind && 
SemaRef.LangOpts.OpenMP >= 505.15k
)
21669
3.43k
          return false;
21670
1.95k
        assert(!StackComponents.empty() &&
21671
1.95k
               "Map clause expression with no components!");
21672
1.95k
        assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21673
1.95k
               "Map clause expression with unexpected base!");
21674
1.95k
        (void)VD;
21675
21676
        // The whole expression in the stack.
21677
1.95k
        const Expr *RE = StackComponents.front().getAssociatedExpression();
21678
21679
        // Expressions must start from the same base. Here we detect at which
21680
        // point both expressions diverge from each other and see if we can
21681
        // detect if the memory referred to both expressions is contiguous and
21682
        // do not overlap.
21683
1.95k
        auto CI = CurComponents.rbegin();
21684
1.95k
        auto CE = CurComponents.rend();
21685
1.95k
        auto SI = StackComponents.rbegin();
21686
1.95k
        auto SE = StackComponents.rend();
21687
4.03k
        for (; CI != CE && 
SI != SE2.68k
;
++CI, ++SI2.07k
) {
21688
21689
          // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
21690
          //  At most one list item can be an array item derived from a given
21691
          //  variable in map clauses of the same construct.
21692
2.25k
          if (CurrentRegionOnly &&
21693
2.25k
              
(926
isa<ArraySubscriptExpr>(CI->getAssociatedExpression())926
||
21694
926
               
isa<OMPArraySectionExpr>(CI->getAssociatedExpression())916
||
21695
926
               
isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())916
) &&
21696
2.25k
              
(10
isa<ArraySubscriptExpr>(SI->getAssociatedExpression())10
||
21697
10
               
isa<OMPArraySectionExpr>(SI->getAssociatedExpression())0
||
21698
10
               
isa<OMPArrayShapingExpr>(SI->getAssociatedExpression())0
)) {
21699
10
            SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21700
10
                         diag::err_omp_multiple_array_items_in_map_clause)
21701
10
                << CI->getAssociatedExpression()->getSourceRange();
21702
10
            SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21703
10
                         diag::note_used_here)
21704
10
                << SI->getAssociatedExpression()->getSourceRange();
21705
10
            return true;
21706
10
          }
21707
21708
          // Do both expressions have the same kind?
21709
2.24k
          if (CI->getAssociatedExpression()->getStmtClass() !=
21710
2.24k
              SI->getAssociatedExpression()->getStmtClass())
21711
20
            break;
21712
21713
          // Are we dealing with different variables/fields?
21714
2.22k
          if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21715
148
            break;
21716
2.22k
        }
21717
        // Check if the extra components of the expressions in the enclosing
21718
        // data environment are redundant for the current base declaration.
21719
        // If they are, the maps completely overlap, which is legal.
21720
2.04k
        
for (; 1.94k
SI != SE;
++SI102
) {
21721
444
          QualType Type;
21722
444
          if (const auto *ASE =
21723
444
                  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21724
20
            Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21725
424
          } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21726
424
                         SI->getAssociatedExpression())) {
21727
188
            const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21728
188
            Type =
21729
188
                OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21730
236
          } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21731
236
                         SI->getAssociatedExpression())) {
21732
0
            Type = OASE->getBase()->getType()->getPointeeType();
21733
0
          }
21734
444
          if (Type.isNull() || 
Type->isAnyPointerType()208
||
21735
444
              checkArrayExpressionDoesNotReferToWholeSize(
21736
110
                  SemaRef, SI->getAssociatedExpression(), Type))
21737
342
            break;
21738
444
        }
21739
21740
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21741
        //  List items of map clauses in the same construct must not share
21742
        //  original storage.
21743
        //
21744
        // If the expressions are exactly the same or one is a subset of the
21745
        // other, it means they are sharing storage.
21746
1.94k
        if (CI == CE && 
SI == SE1.35k
) {
21747
1.17k
          if (CurrentRegionOnly) {
21748
203
            if (CKind == OMPC_map) {
21749
170
              SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21750
170
            } else {
21751
33
              assert(CKind == OMPC_to || CKind == OMPC_from);
21752
33
              SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21753
33
                  << ERange;
21754
33
            }
21755
203
            SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21756
203
                << RE->getSourceRange();
21757
203
            return true;
21758
203
          }
21759
          // If we find the same expression in the enclosing data environment,
21760
          // that is legal.
21761
974
          IsEnclosedByDataEnvironmentExpr = true;
21762
974
          return false;
21763
1.17k
        }
21764
21765
769
        QualType DerivedType =
21766
769
            std::prev(CI)->getAssociatedDeclaration()->getType();
21767
769
        SourceLocation DerivedLoc =
21768
769
            std::prev(CI)->getAssociatedExpression()->getExprLoc();
21769
21770
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21771
        //  If the type of a list item is a reference to a type T then the type
21772
        //  will be considered to be T for all purposes of this clause.
21773
769
        DerivedType = DerivedType.getNonReferenceType();
21774
21775
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
21776
        //  A variable for which the type is pointer and an array section
21777
        //  derived from that variable must not appear as list items of map
21778
        //  clauses of the same construct.
21779
        //
21780
        // Also, cover one of the cases in:
21781
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21782
        //  If any part of the original storage of a list item has corresponding
21783
        //  storage in the device data environment, all of the original storage
21784
        //  must have corresponding storage in the device data environment.
21785
        //
21786
769
        if (DerivedType->isAnyPointerType()) {
21787
366
          if (CI == CE || 
SI == SE288
) {
21788
326
            SemaRef.Diag(
21789
326
                DerivedLoc,
21790
326
                diag::err_omp_pointer_mapped_along_with_derived_section)
21791
326
                << DerivedLoc;
21792
326
            SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21793
326
                << RE->getSourceRange();
21794
326
            return true;
21795
326
          }
21796
40
          if (CI->getAssociatedExpression()->getStmtClass() !=
21797
40
                  SI->getAssociatedExpression()->getStmtClass() ||
21798
40
              CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21799
20
                  SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21800
20
            assert(CI != CE && SI != SE);
21801
20
            SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21802
20
                << DerivedLoc;
21803
20
            SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21804
20
                << RE->getSourceRange();
21805
20
            return true;
21806
20
          }
21807
40
        }
21808
21809
        // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21810
        //  List items of map clauses in the same construct must not share
21811
        //  original storage.
21812
        //
21813
        // An expression is a subset of the other.
21814
423
        if (CurrentRegionOnly && 
(315
CI == CE315
||
SI == SE227
)) {
21815
217
          if (CKind == OMPC_map) {
21816
184
            if (CI != CE || 
SI != SE88
) {
21817
              // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
21818
              // a pointer.
21819
184
              auto Begin =
21820
184
                  CI != CE ? 
CurComponents.begin()96
:
StackComponents.begin()88
;
21821
184
              auto End = CI != CE ? 
CurComponents.end()96
:
StackComponents.end()88
;
21822
184
              auto It = Begin;
21823
302
              while (It != End && !It->getAssociatedDeclaration())
21824
118
                std::advance(It, 1);
21825
184
              assert(It != End &&
21826
184
                     "Expected at least one component with the declaration.");
21827
184
              if (It != Begin && It->getAssociatedDeclaration()
21828
118
                                     ->getType()
21829
118
                                     .getCanonicalType()
21830
118
                                     ->isAnyPointerType()) {
21831
16
                IsEnclosedByDataEnvironmentExpr = false;
21832
16
                EnclosingExpr = nullptr;
21833
16
                return false;
21834
16
              }
21835
184
            }
21836
168
            SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21837
168
          } else {
21838
33
            assert(CKind == OMPC_to || CKind == OMPC_from);
21839
33
            SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21840
33
                << ERange;
21841
33
          }
21842
201
          SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21843
201
              << RE->getSourceRange();
21844
201
          return true;
21845
217
        }
21846
21847
        // The current expression uses the same base as other expression in the
21848
        // data environment but does not contain it completely.
21849
206
        if (!CurrentRegionOnly && 
SI != SE108
)
21850
58
          EnclosingExpr = RE;
21851
21852
        // The current expression is a subset of the expression in the data
21853
        // environment.
21854
206
        IsEnclosedByDataEnvironmentExpr |=
21855
206
            (!CurrentRegionOnly && 
CI != CE108
&&
SI == SE100
);
21856
21857
206
        return false;
21858
423
      });
21859
21860
99.0k
  if (CurrentRegionOnly)
21861
58.8k
    return FoundError;
21862
21863
  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21864
  //  If any part of the original storage of a list item has corresponding
21865
  //  storage in the device data environment, all of the original storage must
21866
  //  have corresponding storage in the device data environment.
21867
  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
21868
  //  If a list item is an element of a structure, and a different element of
21869
  //  the structure has a corresponding list item in the device data environment
21870
  //  prior to a task encountering the construct associated with the map clause,
21871
  //  then the list item must also have a corresponding list item in the device
21872
  //  data environment prior to the task encountering the construct.
21873
  //
21874
40.2k
  if (EnclosingExpr && 
!IsEnclosedByDataEnvironmentExpr48
) {
21875
18
    SemaRef.Diag(ELoc,
21876
18
                 diag::err_omp_original_storage_is_shared_and_does_not_contain)
21877
18
        << ERange;
21878
18
    SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
21879
18
        << EnclosingExpr->getSourceRange();
21880
18
    return true;
21881
18
  }
21882
21883
40.2k
  return FoundError;
21884
40.2k
}
21885
21886
// Look up the user-defined mapper given the mapper name and mapped type, and
21887
// build a reference to it.
21888
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
21889
                                            CXXScopeSpec &MapperIdScopeSpec,
21890
                                            const DeclarationNameInfo &MapperId,
21891
                                            QualType Type,
21892
73.3k
                                            Expr *UnresolvedMapper) {
21893
73.3k
  if (MapperIdScopeSpec.isInvalid())
21894
0
    return ExprError();
21895
  // Get the actual type for the array type.
21896
73.3k
  if (Type->isArrayType()) {
21897
15.6k
    assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
21898
15.6k
    Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
21899
15.6k
  }
21900
  // Find all user-defined mappers with the given MapperId.
21901
73.3k
  SmallVector<UnresolvedSet<8>, 4> Lookups;
21902
73.3k
  LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
21903
73.3k
  Lookup.suppressDiagnostics();
21904
73.3k
  if (S) {
21905
49.9k
    while (S && 
SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)49.3k
) {
21906
697
      NamedDecl *D = Lookup.getRepresentativeDecl();
21907
2.36k
      while (S && 
!S->isDeclScope(D)2.29k
)
21908
1.67k
        S = S->getParent();
21909
697
      if (S)
21910
625
        S = S->getParent();
21911
697
      Lookups.emplace_back();
21912
697
      Lookups.back().append(Lookup.begin(), Lookup.end());
21913
697
      Lookup.clear();
21914
697
    }
21915
49.2k
  } else 
if (auto *24.0k
ULE24.0k
= cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21916
    // Extract the user-defined mappers with the given MapperId.
21917
17.1k
    Lookups.push_back(UnresolvedSet<8>());
21918
17.1k
    for (NamedDecl *D : ULE->decls()) {
21919
36
      auto *DMD = cast<OMPDeclareMapperDecl>(D);
21920
36
      assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
21921
36
      Lookups.back().addDecl(DMD);
21922
36
    }
21923
17.1k
  }
21924
  // Defer the lookup for dependent types. The results will be passed through
21925
  // UnresolvedMapper on instantiation.
21926
73.3k
  if (SemaRef.CurContext->isDependentContext() || 
Type->isDependentType()61.3k
||
21927
73.3k
      
Type->isInstantiationDependentType()61.2k
||
21928
73.3k
      
Type->containsUnexpandedParameterPack()61.2k
||
21929
73.3k
      
filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) 61.2k
{
21930
789
        return !D->isInvalidDecl() &&
21931
789
               (D->getType()->isDependentType() ||
21932
789
                D->getType()->isInstantiationDependentType() ||
21933
789
                D->getType()->containsUnexpandedParameterPack());
21934
12.0k
      })) {
21935
12.0k
    UnresolvedSet<8> URS;
21936
12.0k
    for (const UnresolvedSet<8> &Set : Lookups) {
21937
60
      if (Set.empty())
21938
0
        continue;
21939
60
      URS.append(Set.begin(), Set.end());
21940
60
    }
21941
12.0k
    return UnresolvedLookupExpr::Create(
21942
12.0k
        SemaRef.Context, /*NamingClass=*/nullptr,
21943
12.0k
        MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
21944
12.0k
        /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
21945
12.0k
  }
21946
61.2k
  SourceLocation Loc = MapperId.getLoc();
21947
  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21948
  //  The type must be of struct, union or class type in C and C++
21949
61.2k
  if (!Type->isStructureOrClassType() && 
!Type->isUnionType()43.7k
&&
21950
61.2k
      
(43.7k
MapperIdScopeSpec.isSet()43.7k
||
MapperId.getAsString() != "default"43.7k
)) {
21951
18
    SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
21952
18
    return ExprError();
21953
18
  }
21954
  // Perform argument dependent lookup.
21955
61.2k
  if (SemaRef.getLangOpts().CPlusPlus && 
!MapperIdScopeSpec.isSet()60.5k
)
21956
60.4k
    argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
21957
  // Return the first user-defined mapper with the desired type.
21958
61.2k
  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21959
61.2k
          Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
21960
691
            if (!D->isInvalidDecl() &&
21961
691
                SemaRef.Context.hasSameType(D->getType(), Type))
21962
455
              return D;
21963
236
            return nullptr;
21964
691
          }))
21965
455
    return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21966
  // Find the first user-defined mapper with a type derived from the desired
21967
  // type.
21968
60.7k
  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21969
60.7k
          Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
21970
224
            if (!D->isInvalidDecl() &&
21971
224
                SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
21972
224
                
!Type.isMoreQualifiedThan(D->getType())12
)
21973
12
              return D;
21974
212
            return nullptr;
21975
224
          })) {
21976
12
    CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
21977
12
                       /*DetectVirtual=*/false);
21978
12
    if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
21979
12
      if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
21980
12
              VD->getType().getUnqualifiedType()))) {
21981
12
        if (SemaRef.CheckBaseClassAccess(
21982
12
                Loc, VD->getType(), Type, Paths.front(),
21983
12
                /*DiagID=*/0) != Sema::AR_inaccessible) {
21984
12
          return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21985
12
        }
21986
12
      }
21987
12
    }
21988
12
  }
21989
  // Report error if a mapper is specified, but cannot be found.
21990
60.7k
  if (MapperIdScopeSpec.isSet() || 
MapperId.getAsString() != "default"60.7k
) {
21991
72
    SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
21992
72
        << Type << MapperId.getName();
21993
72
    return ExprError();
21994
72
  }
21995
60.7k
  return ExprEmpty();
21996
60.7k
}
21997
21998
namespace {
21999
// Utility struct that gathers all the related lists associated with a mappable
22000
// expression.
22001
struct MappableVarListInfo {
22002
  // The list of expressions.
22003
  ArrayRef<Expr *> VarList;
22004
  // The list of processed expressions.
22005
  SmallVector<Expr *, 16> ProcessedVarList;
22006
  // The mappble components for each expression.
22007
  OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
22008
  // The base declaration of the variable.
22009
  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
22010
  // The reference to the user-defined mapper associated with every expression.
22011
  SmallVector<Expr *, 16> UDMapperList;
22012
22013
61.6k
  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
22014
    // We have a list of components and base declarations for each entry in the
22015
    // variable list.
22016
61.6k
    VarComponents.reserve(VarList.size());
22017
61.6k
    VarBaseDeclarations.reserve(VarList.size());
22018
61.6k
  }
22019
};
22020
} // namespace
22021
22022
// Check the validity of the provided variable list for the provided clause kind
22023
// \a CKind. In the check process the valid expressions, mappable expression
22024
// components, variables, and user-defined mappers are extracted and used to
22025
// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
22026
// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
22027
// and \a MapperId are expected to be valid if the clause kind is 'map'.
22028
static void checkMappableExpressionList(
22029
    Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
22030
    MappableVarListInfo &MVLI, SourceLocation StartLoc,
22031
    CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
22032
    ArrayRef<Expr *> UnresolvedMappers,
22033
    OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
22034
    ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt,
22035
56.8k
    bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
22036
  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
22037
56.8k
  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
22038
56.8k
         "Unexpected clause kind with mappable expressions!");
22039
22040
  // If the identifier of user-defined mapper is not specified, it is "default".
22041
  // We do not change the actual name in this clause to distinguish whether a
22042
  // mapper is specified explicitly, i.e., it is not explicitly specified when
22043
  // MapperId.getName() is empty.
22044
56.8k
  if (!MapperId.getName() || 
MapperId.getName().isEmpty()533
) {
22045
56.2k
    auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
22046
56.2k
    MapperId.setName(DeclNames.getIdentifier(
22047
56.2k
        &SemaRef.getASTContext().Idents.get("default")));
22048
56.2k
    MapperId.setLoc(StartLoc);
22049
56.2k
  }
22050
22051
  // Iterators to find the current unresolved mapper expression.
22052
56.8k
  auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
22053
56.8k
  bool UpdateUMIt = false;
22054
56.8k
  Expr *UnresolvedMapper = nullptr;
22055
22056
56.8k
  bool HasHoldModifier =
22057
56.8k
      llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
22058
22059
  // Keep track of the mappable components and base declarations in this clause.
22060
  // Each entry in the list is going to have a list of components associated. We
22061
  // record each set of the components so that we can build the clause later on.
22062
  // In the end we should have the same amount of declarations and component
22063
  // lists.
22064
22065
70.2k
  for (Expr *RE : MVLI.VarList) {
22066
70.2k
    assert(RE && "Null expr in omp to/from/map clause");
22067
70.2k
    SourceLocation ELoc = RE->getExprLoc();
22068
22069
    // Find the current unresolved mapper expression.
22070
70.2k
    if (UpdateUMIt && 
UMIt != UMEnd16.6k
) {
22071
3.93k
      UMIt++;
22072
3.93k
      assert(
22073
3.93k
          UMIt != UMEnd &&
22074
3.93k
          "Expect the size of UnresolvedMappers to match with that of VarList");
22075
3.93k
    }
22076
70.2k
    UpdateUMIt = true;
22077
70.2k
    if (UMIt != UMEnd)
22078
17.9k
      UnresolvedMapper = *UMIt;
22079
22080
70.2k
    const Expr *VE = RE->IgnoreParenLValueCasts();
22081
22082
70.2k
    if (VE->isValueDependent() || 
VE->isTypeDependent()60.4k
||
22083
70.2k
        
VE->isInstantiationDependent()60.4k
||
22084
70.2k
        
VE->containsUnexpandedParameterPack()60.4k
) {
22085
      // Try to find the associated user-defined mapper.
22086
9.77k
      ExprResult ER = buildUserDefinedMapperRef(
22087
9.77k
          SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22088
9.77k
          VE->getType().getCanonicalType(), UnresolvedMapper);
22089
9.77k
      if (ER.isInvalid())
22090
0
        continue;
22091
9.77k
      MVLI.UDMapperList.push_back(ER.get());
22092
      // We can only analyze this information once the missing information is
22093
      // resolved.
22094
9.77k
      MVLI.ProcessedVarList.push_back(RE);
22095
9.77k
      continue;
22096
9.77k
    }
22097
22098
60.4k
    Expr *SimpleExpr = RE->IgnoreParenCasts();
22099
22100
60.4k
    if (!RE->isLValue()) {
22101
246
      if (SemaRef.getLangOpts().OpenMP < 50) {
22102
82
        SemaRef.Diag(
22103
82
            ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
22104
82
            << RE->getSourceRange();
22105
164
      } else {
22106
164
        SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
22107
164
            << getOpenMPClauseName(CKind) << RE->getSourceRange();
22108
164
      }
22109
246
      continue;
22110
246
    }
22111
22112
60.2k
    OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
22113
60.2k
    ValueDecl *CurDeclaration = nullptr;
22114
22115
    // Obtain the array or member expression bases if required. Also, fill the
22116
    // components array with all the components identified in the process.
22117
60.2k
    const Expr *BE =
22118
60.2k
        checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
22119
60.2k
                                     DSAS->getCurrentDirective(), NoDiagnose);
22120
60.2k
    if (!BE)
22121
1.05k
      continue;
22122
22123
59.1k
    assert(!CurComponents.empty() &&
22124
59.1k
           "Invalid mappable expression information.");
22125
22126
59.1k
    if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
22127
      // Add store "this" pointer to class in DSAStackTy for future checking
22128
123
      DSAS->addMappedClassesQualTypes(TE->getType());
22129
      // Try to find the associated user-defined mapper.
22130
123
      ExprResult ER = buildUserDefinedMapperRef(
22131
123
          SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22132
123
          VE->getType().getCanonicalType(), UnresolvedMapper);
22133
123
      if (ER.isInvalid())
22134
0
        continue;
22135
123
      MVLI.UDMapperList.push_back(ER.get());
22136
      // Skip restriction checking for variable or field declarations
22137
123
      MVLI.ProcessedVarList.push_back(RE);
22138
123
      MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22139
123
      MVLI.VarComponents.back().append(CurComponents.begin(),
22140
123
                                       CurComponents.end());
22141
123
      MVLI.VarBaseDeclarations.push_back(nullptr);
22142
123
      continue;
22143
123
    }
22144
22145
    // For the following checks, we rely on the base declaration which is
22146
    // expected to be associated with the last component. The declaration is
22147
    // expected to be a variable or a field (if 'this' is being mapped).
22148
59.0k
    CurDeclaration = CurComponents.back().getAssociatedDeclaration();
22149
59.0k
    assert(CurDeclaration && "Null decl on map clause.");
22150
59.0k
    assert(
22151
59.0k
        CurDeclaration->isCanonicalDecl() &&
22152
59.0k
        "Expecting components to have associated only canonical declarations.");
22153
22154
59.0k
    auto *VD = dyn_cast<VarDecl>(CurDeclaration);
22155
59.0k
    const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
22156
22157
59.0k
    assert((VD || FD) && "Only variables or fields are expected here!");
22158
59.0k
    (void)FD;
22159
22160
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
22161
    // threadprivate variables cannot appear in a map clause.
22162
    // OpenMP 4.5 [2.10.5, target update Construct]
22163
    // threadprivate variables cannot appear in a from clause.
22164
59.0k
    if (VD && 
DSAS->isThreadPrivate(VD)55.5k
) {
22165
229
      if (NoDiagnose)
22166
1
        continue;
22167
228
      DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
22168
228
      SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
22169
228
          << getOpenMPClauseName(CKind);
22170
228
      reportOriginalDsa(SemaRef, DSAS, VD, DVar);
22171
228
      continue;
22172
229
    }
22173
22174
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
22175
    //  A list item cannot appear in both a map clause and a data-sharing
22176
    //  attribute clause on the same construct.
22177
22178
    // Check conflicts with other map clause expressions. We check the conflicts
22179
    // with the current construct separately from the enclosing data
22180
    // environment, because the restrictions are different. We only have to
22181
    // check conflicts across regions for the map clauses.
22182
58.8k
    if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
22183
58.8k
                          /*CurrentRegionOnly=*/true, CurComponents, CKind))
22184
594
      break;
22185
58.2k
    if (CKind == OMPC_map &&
22186
58.2k
        
(54.3k
SemaRef.getLangOpts().OpenMP <= 4554.3k
||
StartLoc.isValid()38.3k
) &&
22187
58.2k
        checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
22188
40.2k
                          /*CurrentRegionOnly=*/false, CurComponents, CKind))
22189
184
      break;
22190
22191
    // OpenMP 4.5 [2.10.5, target update Construct]
22192
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
22193
    //  If the type of a list item is a reference to a type T then the type will
22194
    //  be considered to be T for all purposes of this clause.
22195
58.0k
    auto I = llvm::find_if(
22196
58.0k
        CurComponents,
22197
70.0k
        [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
22198
70.0k
          return MC.getAssociatedDeclaration();
22199
70.0k
        });
22200
58.0k
    assert(I != CurComponents.end() && "Null decl on map clause.");
22201
58.0k
    (void)I;
22202
58.0k
    QualType Type;
22203
58.0k
    auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
22204
58.0k
    auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
22205
58.0k
    auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
22206
58.0k
    if (ASE) {
22207
652
      Type = ASE->getType().getNonReferenceType();
22208
57.4k
    } else if (OASE) {
22209
6.69k
      QualType BaseType =
22210
6.69k
          OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
22211
6.69k
      if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
22212
4.48k
        Type = ATy->getElementType();
22213
2.20k
      else
22214
2.20k
        Type = BaseType->getPointeeType();
22215
6.69k
      Type = Type.getNonReferenceType();
22216
50.7k
    } else if (OAShE) {
22217
85
      Type = OAShE->getBase()->getType()->getPointeeType();
22218
50.6k
    } else {
22219
50.6k
      Type = VE->getType();
22220
50.6k
    }
22221
22222
    // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
22223
    // A list item in a to or from clause must have a mappable type.
22224
    // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
22225
    //  A list item must have a mappable type.
22226
58.0k
    if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
22227
58.0k
                           DSAS, Type, /*FullCheck=*/true))
22228
772
      continue;
22229
22230
57.2k
    if (CKind == OMPC_map) {
22231
      // target enter data
22232
      // OpenMP [2.10.2, Restrictions, p. 99]
22233
      // A map-type must be specified in all map clauses and must be either
22234
      // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if
22235
      // no map type is present.
22236
53.4k
      OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
22237
53.4k
      if (DKind == OMPD_target_enter_data &&
22238
53.4k
          
!(2.37k
MapType == OMPC_MAP_to2.37k
||
MapType == OMPC_MAP_alloc412
||
22239
2.37k
            
SemaRef.getLangOpts().OpenMP >= 5240
)) {
22240
40
        SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22241
40
            << (IsMapTypeImplicit ? 
18
:
032
)
22242
40
            << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22243
40
            << getOpenMPDirectiveName(DKind);
22244
40
        continue;
22245
40
      }
22246
22247
      // target exit_data
22248
      // OpenMP [2.10.3, Restrictions, p. 102]
22249
      // A map-type must be specified in all map clauses and must be either
22250
      // from, release, or delete. Starting with OpenMP 5.2 the default map
22251
      // type is `from` if no map type is present.
22252
53.4k
      if (DKind == OMPD_target_exit_data &&
22253
53.4k
          
!(2.32k
MapType == OMPC_MAP_from2.32k
||
MapType == OMPC_MAP_release512
||
22254
2.32k
            
MapType == OMPC_MAP_delete118
||
SemaRef.getLangOpts().OpenMP >= 5232
)) {
22255
32
        SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22256
32
            << (IsMapTypeImplicit ? 
18
:
024
)
22257
32
            << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22258
32
            << getOpenMPDirectiveName(DKind);
22259
32
        continue;
22260
32
      }
22261
22262
      // The 'ompx_hold' modifier is specifically intended to be used on a
22263
      // 'target' or 'target data' directive to prevent data from being unmapped
22264
      // during the associated statement.  It is not permitted on a 'target
22265
      // enter data' or 'target exit data' directive, which have no associated
22266
      // statement.
22267
53.3k
      if ((DKind == OMPD_target_enter_data || 
DKind == OMPD_target_exit_data51.0k
) &&
22268
53.3k
          
HasHoldModifier4.62k
) {
22269
20
        SemaRef.Diag(StartLoc,
22270
20
                     diag::err_omp_invalid_map_type_modifier_for_directive)
22271
20
            << getOpenMPSimpleClauseTypeName(OMPC_map,
22272
20
                                             OMPC_MAP_MODIFIER_ompx_hold)
22273
20
            << getOpenMPDirectiveName(DKind);
22274
20
        continue;
22275
20
      }
22276
22277
      // target, target data
22278
      // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
22279
      // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
22280
      // A map-type in a map clause must be to, from, tofrom or alloc
22281
53.3k
      if ((DKind == OMPD_target_data ||
22282
53.3k
           
isOpenMPTargetExecutionDirective(DKind)46.9k
) &&
22283
53.3k
          
!(48.3k
MapType == OMPC_MAP_to48.3k
||
MapType == OMPC_MAP_from46.3k
||
22284
48.3k
            
MapType == OMPC_MAP_tofrom45.2k
||
MapType == OMPC_MAP_alloc853
)) {
22285
170
        SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22286
170
            << (IsMapTypeImplicit ? 
10
: 0)
22287
170
            << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22288
170
            << getOpenMPDirectiveName(DKind);
22289
170
        continue;
22290
170
      }
22291
22292
      // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
22293
      // A list item cannot appear in both a map clause and a data-sharing
22294
      // attribute clause on the same construct
22295
      //
22296
      // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
22297
      // A list item cannot appear in both a map clause and a data-sharing
22298
      // attribute clause on the same construct unless the construct is a
22299
      // combined construct.
22300
53.1k
      if (VD && 
(49.7k
(49.7k
SemaRef.LangOpts.OpenMP <= 4549.7k
&&
22301
49.7k
                  
isOpenMPTargetExecutionDirective(DKind)14.4k
) ||
22302
49.7k
                 
DKind == OMPD_target38.7k
)) {
22303
23.1k
        DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
22304
23.1k
        if (isOpenMPPrivate(DVar.CKind)) {
22305
57
          SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22306
57
              << getOpenMPClauseName(DVar.CKind)
22307
57
              << getOpenMPClauseName(OMPC_map)
22308
57
              << getOpenMPDirectiveName(DSAS->getCurrentDirective());
22309
57
          reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
22310
57
          continue;
22311
57
        }
22312
23.1k
      }
22313
53.1k
    }
22314
22315
    // Try to find the associated user-defined mapper.
22316
56.9k
    ExprResult ER = buildUserDefinedMapperRef(
22317
56.9k
        SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22318
56.9k
        Type.getCanonicalType(), UnresolvedMapper);
22319
56.9k
    if (ER.isInvalid())
22320
90
      continue;
22321
56.8k
    MVLI.UDMapperList.push_back(ER.get());
22322
22323
    // Save the current expression.
22324
56.8k
    MVLI.ProcessedVarList.push_back(RE);
22325
22326
    // Store the components in the stack so that they can be used to check
22327
    // against other clauses later on.
22328
56.8k
    DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
22329
56.8k
                                          /*WhereFoundClauseKind=*/OMPC_map);
22330
22331
    // Save the components and declaration to create the clause. For purposes of
22332
    // the clause creation, any component list that has base 'this' uses
22333
    // null as base declaration.
22334
56.8k
    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22335
56.8k
    MVLI.VarComponents.back().append(CurComponents.begin(),
22336
56.8k
                                     CurComponents.end());
22337
56.8k
    MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? 
nullptr3.54k
22338
56.8k
                                                           : 
CurDeclaration53.3k
);
22339
56.8k
  }
22340
56.8k
}
22341
22342
OMPClause *Sema::ActOnOpenMPMapClause(
22343
    Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
22344
    ArrayRef<SourceLocation> MapTypeModifiersLoc,
22345
    CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22346
    OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
22347
    SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22348
    const OMPVarListLocTy &Locs, bool NoDiagnose,
22349
52.2k
    ArrayRef<Expr *> UnresolvedMappers) {
22350
52.2k
  OpenMPMapModifierKind Modifiers[] = {
22351
52.2k
      OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22352
52.2k
      OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22353
52.2k
      OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
22354
52.2k
  SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
22355
22356
52.2k
  if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType(
22357
48
                              BuiltinType::OMPIterator))
22358
0
    Diag(IteratorModifier->getExprLoc(),
22359
0
         diag::err_omp_map_modifier_not_iterator);
22360
22361
  // Process map-type-modifiers, flag errors for duplicate modifiers.
22362
52.2k
  unsigned Count = 0;
22363
142k
  for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; 
++I89.7k
) {
22364
89.7k
    if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
22365
89.7k
        
llvm::is_contained(Modifiers, MapTypeModifiers[I])5.02k
) {
22366
135
      Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
22367
135
      continue;
22368
135
    }
22369
89.6k
    assert(Count < NumberOfOMPMapClauseModifiers &&
22370
89.6k
           "Modifiers exceed the allowed number of map type modifiers");
22371
89.6k
    Modifiers[Count] = MapTypeModifiers[I];
22372
89.6k
    ModifiersLoc[Count] = MapTypeModifiersLoc[I];
22373
89.6k
    ++Count;
22374
89.6k
  }
22375
22376
52.2k
  MappableVarListInfo MVLI(VarList);
22377
52.2k
  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
22378
52.2k
                              MapperIdScopeSpec, MapperId, UnresolvedMappers,
22379
52.2k
                              MapType, Modifiers, IsMapTypeImplicit,
22380
52.2k
                              NoDiagnose);
22381
22382
  // We need to produce a map clause even if we don't have variables so that
22383
  // other diagnostics related with non-existing map clauses are accurate.
22384
52.2k
  return OMPMapClause::Create(
22385
52.2k
      Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22386
52.2k
      MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
22387
52.2k
      ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(Context), MapperId,
22388
52.2k
      MapType, IsMapTypeImplicit, MapLoc);
22389
52.2k
}
22390
22391
QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
22392
928
                                               TypeResult ParsedType) {
22393
928
  assert(ParsedType.isUsable());
22394
22395
928
  QualType ReductionType = GetTypeFromParser(ParsedType.get());
22396
928
  if (ReductionType.isNull())
22397
0
    return QualType();
22398
22399
  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
22400
  // A type name in a declare reduction directive cannot be a function type, an
22401
  // array type, a reference type, or a type qualified with const, volatile or
22402
  // restrict.
22403
928
  if (ReductionType.hasQualifiers()) {
22404
16
    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
22405
16
    return QualType();
22406
16
  }
22407
22408
912
  if (ReductionType->isFunctionType()) {
22409
8
    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
22410
8
    return QualType();
22411
8
  }
22412
904
  if (ReductionType->isReferenceType()) {
22413
18
    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
22414
18
    return QualType();
22415
18
  }
22416
886
  if (ReductionType->isArrayType()) {
22417
8
    Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22418
8
    return QualType();
22419
8
  }
22420
878
  return ReductionType;
22421
886
}
22422
22423
Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
22424
    Scope *S, DeclContext *DC, DeclarationName Name,
22425
    ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22426
768
    AccessSpecifier AS, Decl *PrevDeclInScope) {
22427
768
  SmallVector<Decl *, 8> Decls;
22428
768
  Decls.reserve(ReductionTypes.size());
22429
22430
768
  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
22431
768
                      forRedeclarationInCurContext());
22432
  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
22433
  // A reduction-identifier may not be re-declared in the current scope for the
22434
  // same type or for a type that is compatible according to the base language
22435
  // rules.
22436
768
  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22437
768
  OMPDeclareReductionDecl *PrevDRD = nullptr;
22438
768
  bool InCompoundScope = true;
22439
768
  if (S != nullptr) {
22440
    // Find previous declaration with the same name not referenced in other
22441
    // declarations.
22442
624
    FunctionScopeInfo *ParentFn = getEnclosingFunction();
22443
624
    InCompoundScope =
22444
624
        (ParentFn != nullptr) && 
!ParentFn->CompoundScopes.empty()162
;
22445
624
    LookupName(Lookup, S);
22446
624
    FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22447
624
                         /*AllowInlineNamespace=*/false);
22448
624
    llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22449
624
    LookupResult::Filter Filter = Lookup.makeFilter();
22450
702
    while (Filter.hasNext()) {
22451
78
      auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22452
78
      if (InCompoundScope) {
22453
37
        auto I = UsedAsPrevious.find(PrevDecl);
22454
37
        if (I == UsedAsPrevious.end())
22455
33
          UsedAsPrevious[PrevDecl] = false;
22456
37
        if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
22457
4
          UsedAsPrevious[D] = true;
22458
37
      }
22459
78
      PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22460
78
          PrevDecl->getLocation();
22461
78
    }
22462
624
    Filter.done();
22463
624
    if (InCompoundScope) {
22464
162
      for (const auto &PrevData : UsedAsPrevious) {
22465
35
        if (!PrevData.second) {
22466
33
          PrevDRD = PrevData.first;
22467
33
          break;
22468
33
        }
22469
35
      }
22470
162
    }
22471
624
  } else 
if (144
PrevDeclInScope != nullptr144
) {
22472
20
    auto *PrevDRDInScope = PrevDRD =
22473
20
        cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22474
20
    do {
22475
20
      PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22476
20
          PrevDRDInScope->getLocation();
22477
20
      PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22478
20
    } while (PrevDRDInScope != nullptr);
22479
20
  }
22480
856
  for (const auto &TyData : ReductionTypes) {
22481
856
    const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22482
856
    bool Invalid = false;
22483
856
    if (I != PreviousRedeclTypes.end()) {
22484
48
      Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22485
48
          << TyData.first;
22486
48
      Diag(I->second, diag::note_previous_definition);
22487
48
      Invalid = true;
22488
48
    }
22489
856
    PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22490
856
    auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
22491
856
                                                Name, TyData.first, PrevDRD);
22492
856
    DC->addDecl(DRD);
22493
856
    DRD->setAccess(AS);
22494
856
    Decls.push_back(DRD);
22495
856
    if (Invalid)
22496
48
      DRD->setInvalidDecl();
22497
808
    else
22498
808
      PrevDRD = DRD;
22499
856
  }
22500
22501
768
  return DeclGroupPtrTy::make(
22502
768
      DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
22503
768
}
22504
22505
856
void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
22506
856
  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22507
22508
  // Enter new function scope.
22509
856
  PushFunctionScope();
22510
856
  setFunctionHasBranchProtectedScope();
22511
856
  getCurFunction()->setHasOMPDeclareReductionCombiner();
22512
22513
856
  if (S != nullptr)
22514
712
    PushDeclContext(S, DRD);
22515
144
  else
22516
144
    CurContext = DRD;
22517
22518
856
  PushExpressionEvaluationContext(
22519
856
      ExpressionEvaluationContext::PotentiallyEvaluated);
22520
22521
856
  QualType ReductionType = DRD->getType();
22522
  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
22523
  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
22524
  // uses semantics of argument handles by value, but it should be passed by
22525
  // reference. C lang does not support references, so pass all parameters as
22526
  // pointers.
22527
  // Create 'T omp_in;' variable.
22528
856
  VarDecl *OmpInParm =
22529
856
      buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
22530
  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
22531
  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
22532
  // uses semantics of argument handles by value, but it should be passed by
22533
  // reference. C lang does not support references, so pass all parameters as
22534
  // pointers.
22535
  // Create 'T omp_out;' variable.
22536
856
  VarDecl *OmpOutParm =
22537
856
      buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
22538
856
  if (S != nullptr) {
22539
712
    PushOnScopeChains(OmpInParm, S);
22540
712
    PushOnScopeChains(OmpOutParm, S);
22541
712
  } else {
22542
144
    DRD->addDecl(OmpInParm);
22543
144
    DRD->addDecl(OmpOutParm);
22544
144
  }
22545
856
  Expr *InE =
22546
856
      ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
22547
856
  Expr *OutE =
22548
856
      ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
22549
856
  DRD->setCombinerData(InE, OutE);
22550
856
}
22551
22552
856
void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
22553
856
  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22554
856
  DiscardCleanupsInEvaluationContext();
22555
856
  PopExpressionEvaluationContext();
22556
22557
856
  PopDeclContext();
22558
856
  PopFunctionScopeInfo();
22559
22560
856
  if (Combiner != nullptr)
22561
802
    DRD->setCombiner(Combiner);
22562
54
  else
22563
54
    DRD->setInvalidDecl();
22564
856
}
22565
22566
296
VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
22567
296
  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22568
22569
  // Enter new function scope.
22570
296
  PushFunctionScope();
22571
296
  setFunctionHasBranchProtectedScope();
22572
22573
296
  if (S != nullptr)
22574
244
    PushDeclContext(S, DRD);
22575
52
  else
22576
52
    CurContext = DRD;
22577
22578
296
  PushExpressionEvaluationContext(
22579
296
      ExpressionEvaluationContext::PotentiallyEvaluated);
22580
22581
296
  QualType ReductionType = DRD->getType();
22582
  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
22583
  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
22584
  // uses semantics of argument handles by value, but it should be passed by
22585
  // reference. C lang does not support references, so pass all parameters as
22586
  // pointers.
22587
  // Create 'T omp_priv;' variable.
22588
296
  VarDecl *OmpPrivParm =
22589
296
      buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
22590
  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
22591
  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
22592
  // uses semantics of argument handles by value, but it should be passed by
22593
  // reference. C lang does not support references, so pass all parameters as
22594
  // pointers.
22595
  // Create 'T omp_orig;' variable.
22596
296
  VarDecl *OmpOrigParm =
22597
296
      buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
22598
296
  if (S != nullptr) {
22599
244
    PushOnScopeChains(OmpPrivParm, S);
22600
244
    PushOnScopeChains(OmpOrigParm, S);
22601
244
  } else {
22602
52
    DRD->addDecl(OmpPrivParm);
22603
52
    DRD->addDecl(OmpOrigParm);
22604
52
  }
22605
296
  Expr *OrigE =
22606
296
      ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
22607
296
  Expr *PrivE =
22608
296
      ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
22609
296
  DRD->setInitializerData(OrigE, PrivE);
22610
296
  return OmpPrivParm;
22611
296
}
22612
22613
void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
22614
296
                                                     VarDecl *OmpPrivParm) {
22615
296
  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22616
296
  DiscardCleanupsInEvaluationContext();
22617
296
  PopExpressionEvaluationContext();
22618
22619
296
  PopDeclContext();
22620
296
  PopFunctionScopeInfo();
22621
22622
296
  if (Initializer != nullptr) {
22623
75
    DRD->setInitializer(Initializer, OMPDeclareReductionInitKind::Call);
22624
221
  } else if (OmpPrivParm->hasInit()) {
22625
161
    DRD->setInitializer(OmpPrivParm->getInit(),
22626
161
                        OmpPrivParm->isDirectInit()
22627
161
                            ? 
OMPDeclareReductionInitKind::Direct0
22628
161
                            : OMPDeclareReductionInitKind::Copy);
22629
161
  } else {
22630
60
    DRD->setInvalidDecl();
22631
60
  }
22632
296
}
22633
22634
Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
22635
768
    Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
22636
856
  for (Decl *D : DeclReductions.get()) {
22637
856
    if (IsValid) {
22638
720
      if (S)
22639
578
        PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
22640
578
                          /*AddToContext=*/false);
22641
720
    } else {
22642
136
      D->setInvalidDecl();
22643
136
    }
22644
856
  }
22645
768
  return DeclReductions;
22646
768
}
22647
22648
397
TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
22649
397
  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
22650
397
  QualType T = TInfo->getType();
22651
397
  if (D.isInvalidType())
22652
18
    return true;
22653
22654
379
  if (getLangOpts().CPlusPlus) {
22655
    // Check that there are no default arguments (C++ only).
22656
211
    CheckExtraCXXDefaultArguments(D);
22657
211
  }
22658
22659
379
  return CreateParsedType(T, TInfo);
22660
397
}
22661
22662
QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
22663
391
                                            TypeResult ParsedType) {
22664
391
  assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
22665
22666
391
  QualType MapperType = GetTypeFromParser(ParsedType.get());
22667
391
  assert(!MapperType.isNull() && "Expect valid mapper type");
22668
22669
  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22670
  //  The type must be of struct, union or class type in C and C++
22671
391
  if (!MapperType->isStructureOrClassType() && 
!MapperType->isUnionType()10
) {
22672
10
    Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22673
10
    return QualType();
22674
10
  }
22675
381
  return MapperType;
22676
391
}
22677
22678
Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
22679
    Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
22680
    SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
22681
377
    Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
22682
377
  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
22683
377
                      forRedeclarationInCurContext());
22684
  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22685
  //  A mapper-identifier may not be redeclared in the current scope for the
22686
  //  same type or for a type that is compatible according to the base language
22687
  //  rules.
22688
377
  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22689
377
  OMPDeclareMapperDecl *PrevDMD = nullptr;
22690
377
  bool InCompoundScope = true;
22691
377
  if (S != nullptr) {
22692
    // Find previous declaration with the same name not referenced in other
22693
    // declarations.
22694
349
    FunctionScopeInfo *ParentFn = getEnclosingFunction();
22695
349
    InCompoundScope =
22696
349
        (ParentFn != nullptr) && 
!ParentFn->CompoundScopes.empty()107
;
22697
349
    LookupName(Lookup, S);
22698
349
    FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22699
349
                         /*AllowInlineNamespace=*/false);
22700
349
    llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22701
349
    LookupResult::Filter Filter = Lookup.makeFilter();
22702
405
    while (Filter.hasNext()) {
22703
56
      auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22704
56
      if (InCompoundScope) {
22705
18
        auto I = UsedAsPrevious.find(PrevDecl);
22706
18
        if (I == UsedAsPrevious.end())
22707
18
          UsedAsPrevious[PrevDecl] = false;
22708
18
        if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
22709
0
          UsedAsPrevious[D] = true;
22710
18
      }
22711
56
      PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22712
56
          PrevDecl->getLocation();
22713
56
    }
22714
349
    Filter.done();
22715
349
    if (InCompoundScope) {
22716
107
      for (const auto &PrevData : UsedAsPrevious) {
22717
18
        if (!PrevData.second) {
22718
18
          PrevDMD = PrevData.first;
22719
18
          break;
22720
18
        }
22721
18
      }
22722
107
    }
22723
349
  } else 
if (28
PrevDeclInScope28
) {
22724
4
    auto *PrevDMDInScope = PrevDMD =
22725
4
        cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22726
4
    do {
22727
4
      PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22728
4
          PrevDMDInScope->getLocation();
22729
4
      PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22730
4
    } while (PrevDMDInScope != nullptr);
22731
4
  }
22732
377
  const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
22733
377
  bool Invalid = false;
22734
377
  if (I != PreviousRedeclTypes.end()) {
22735
28
    Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22736
28
        << MapperType << Name;
22737
28
    Diag(I->second, diag::note_previous_definition);
22738
28
    Invalid = true;
22739
28
  }
22740
  // Build expressions for implicit maps of data members with 'default'
22741
  // mappers.
22742
377
  SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
22743
377
                                                  Clauses.end());
22744
377
  if (LangOpts.OpenMP >= 50)
22745
375
    processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
22746
377
  auto *DMD =
22747
377
      OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
22748
377
                                   ClausesWithImplicit, PrevDMD);
22749
377
  if (S)
22750
349
    PushOnScopeChains(DMD, S);
22751
28
  else
22752
28
    DC->addDecl(DMD);
22753
377
  DMD->setAccess(AS);
22754
377
  if (Invalid)
22755
28
    DMD->setInvalidDecl();
22756
22757
377
  auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22758
377
  VD->setDeclContext(DMD);
22759
377
  VD->setLexicalDeclContext(DMD);
22760
377
  DMD->addDecl(VD);
22761
377
  DMD->setMapperVarRef(MapperVarRef);
22762
22763
377
  return DeclGroupPtrTy::make(DeclGroupRef(DMD));
22764
377
}
22765
22766
ExprResult
22767
Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
22768
                                               SourceLocation StartLoc,
22769
377
                                               DeclarationName VN) {
22770
377
  TypeSourceInfo *TInfo =
22771
377
      Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
22772
377
  auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
22773
377
                             StartLoc, StartLoc, VN.getAsIdentifierInfo(),
22774
377
                             MapperType, TInfo, SC_None);
22775
377
  if (S)
22776
349
    PushOnScopeChains(VD, S, /*AddToContext=*/false);
22777
377
  Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
22778
377
  DSAStack->addDeclareMapperVarRef(E);
22779
377
  return E;
22780
377
}
22781
22782
258
void Sema::ActOnOpenMPIteratorVarDecl(VarDecl *VD) {
22783
258
  if (DSAStack->getDeclareMapperVarRef())
22784
12
    DSAStack->addIteratorVarDecl(VD);
22785
258
}
22786
22787
1.93M
bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
22788
1.93M
  assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22789
1.93M
  const Expr *Ref = DSAStack->getDeclareMapperVarRef();
22790
1.93M
  if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22791
489
    if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
22792
463
      return true;
22793
26
    if (VD->isUsableInConstantExpressions(Context))
22794
4
      return true;
22795
22
    if (LangOpts.OpenMP >= 52 && 
DSAStack10
->isIteratorVarDecl(VD)10
)
22796
6
      return true;
22797
16
    return false;
22798
22
  }
22799
1.93M
  return true;
22800
1.93M
}
22801
22802
16
const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
22803
16
  assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22804
16
  return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
22805
16
}
22806
22807
OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
22808
                                           SourceLocation StartLoc,
22809
                                           SourceLocation LParenLoc,
22810
2.00k
                                           SourceLocation EndLoc) {
22811
2.00k
  Expr *ValExpr = NumTeams;
22812
2.00k
  Stmt *HelperValStmt = nullptr;
22813
22814
  // OpenMP [teams Constrcut, Restrictions]
22815
  // The num_teams expression must evaluate to a positive integer value.
22816
2.00k
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
22817
2.00k
                                 /*StrictlyPositive=*/true))
22818
44
    return nullptr;
22819
22820
1.96k
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22821
1.96k
  OpenMPDirectiveKind CaptureRegion =
22822
1.96k
      getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
22823
1.96k
  if (CaptureRegion != OMPD_unknown && 
!CurContext->isDependentContext()1.24k
) {
22824
899
    ValExpr = MakeFullExpr(ValExpr).get();
22825
899
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22826
899
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22827
899
    HelperValStmt = buildPreInits(Context, Captures);
22828
899
  }
22829
22830
1.96k
  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
22831
1.96k
                                         StartLoc, LParenLoc, EndLoc);
22832
2.00k
}
22833
22834
OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
22835
                                              SourceLocation StartLoc,
22836
                                              SourceLocation LParenLoc,
22837
1.67k
                                              SourceLocation EndLoc) {
22838
1.67k
  Expr *ValExpr = ThreadLimit;
22839
1.67k
  Stmt *HelperValStmt = nullptr;
22840
22841
  // OpenMP [teams Constrcut, Restrictions]
22842
  // The thread_limit expression must evaluate to a positive integer value.
22843
1.67k
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
22844
1.67k
                                 /*StrictlyPositive=*/true))
22845
36
    return nullptr;
22846
22847
1.64k
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22848
1.64k
  OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
22849
1.64k
      DKind, OMPC_thread_limit, LangOpts.OpenMP);
22850
1.64k
  if (CaptureRegion != OMPD_unknown && 
!CurContext->isDependentContext()962
) {
22851
711
    ValExpr = MakeFullExpr(ValExpr).get();
22852
711
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22853
711
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22854
711
    HelperValStmt = buildPreInits(Context, Captures);
22855
711
  }
22856
22857
1.64k
  return new (Context) OMPThreadLimitClause(
22858
1.64k
      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22859
1.67k
}
22860
22861
OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
22862
                                           SourceLocation StartLoc,
22863
                                           SourceLocation LParenLoc,
22864
1.03k
                                           SourceLocation EndLoc) {
22865
1.03k
  Expr *ValExpr = Priority;
22866
1.03k
  Stmt *HelperValStmt = nullptr;
22867
1.03k
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22868
22869
  // OpenMP [2.9.1, task Constrcut]
22870
  // The priority-value is a non-negative numerical scalar expression.
22871
1.03k
  if (!isNonNegativeIntegerValue(
22872
1.03k
          ValExpr, *this, OMPC_priority,
22873
1.03k
          /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22874
1.03k
          DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22875
44
    return nullptr;
22876
22877
990
  return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
22878
990
                                         StartLoc, LParenLoc, EndLoc);
22879
1.03k
}
22880
22881
OMPClause *Sema::ActOnOpenMPGrainsizeClause(
22882
    OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize,
22883
    SourceLocation StartLoc, SourceLocation LParenLoc,
22884
1.39k
    SourceLocation ModifierLoc, SourceLocation EndLoc) {
22885
1.39k
  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22886
1.39k
         "Unexpected grainsize modifier in OpenMP < 51.");
22887
22888
1.39k
  if (ModifierLoc.isValid() && 
Modifier == OMPC_GRAINSIZE_unknown78
) {
22889
18
    std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0,
22890
18
                                                 OMPC_GRAINSIZE_unknown);
22891
18
    Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22892
18
        << Values << getOpenMPClauseName(OMPC_grainsize);
22893
18
    return nullptr;
22894
18
  }
22895
22896
1.37k
  Expr *ValExpr = Grainsize;
22897
1.37k
  Stmt *HelperValStmt = nullptr;
22898
1.37k
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22899
22900
  // OpenMP [2.9.2, taskloop Constrcut]
22901
  // The parameter of the grainsize clause must be a positive integer
22902
  // expression.
22903
1.37k
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
22904
1.37k
                                 /*StrictlyPositive=*/true,
22905
1.37k
                                 /*BuildCapture=*/true,
22906
1.37k
                                 DSAStack->getCurrentDirective(),
22907
1.37k
                                 &CaptureRegion, &HelperValStmt))
22908
152
    return nullptr;
22909
22910
1.22k
  return new (Context)
22911
1.22k
      OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22912
1.22k
                         StartLoc, LParenLoc, ModifierLoc, EndLoc);
22913
1.37k
}
22914
22915
OMPClause *Sema::ActOnOpenMPNumTasksClause(
22916
    OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks,
22917
    SourceLocation StartLoc, SourceLocation LParenLoc,
22918
1.02k
    SourceLocation ModifierLoc, SourceLocation EndLoc) {
22919
1.02k
  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22920
1.02k
         "Unexpected num_tasks modifier in OpenMP < 51.");
22921
22922
1.02k
  if (ModifierLoc.isValid() && 
Modifier == OMPC_NUMTASKS_unknown78
) {
22923
18
    std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0,
22924
18
                                                 OMPC_NUMTASKS_unknown);
22925
18
    Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22926
18
        << Values << getOpenMPClauseName(OMPC_num_tasks);
22927
18
    return nullptr;
22928
18
  }
22929
22930
1.00k
  Expr *ValExpr = NumTasks;
22931
1.00k
  Stmt *HelperValStmt = nullptr;
22932
1.00k
  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22933
22934
  // OpenMP [2.9.2, taskloop Constrcut]
22935
  // The parameter of the num_tasks clause must be a positive integer
22936
  // expression.
22937
1.00k
  if (!isNonNegativeIntegerValue(
22938
1.00k
          ValExpr, *this, OMPC_num_tasks,
22939
1.00k
          /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22940
1.00k
          DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22941
80
    return nullptr;
22942
22943
925
  return new (Context)
22944
925
      OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22945
925
                        StartLoc, LParenLoc, ModifierLoc, EndLoc);
22946
1.00k
}
22947
22948
OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
22949
                                       SourceLocation LParenLoc,
22950
292
                                       SourceLocation EndLoc) {
22951
  // OpenMP [2.13.2, critical construct, Description]
22952
  // ... where hint-expression is an integer constant expression that evaluates
22953
  // to a valid lock hint.
22954
292
  ExprResult HintExpr =
22955
292
      VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
22956
292
  if (HintExpr.isInvalid())
22957
16
    return nullptr;
22958
276
  return new (Context)
22959
276
      OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
22960
292
}
22961
22962
/// Tries to find omp_event_handle_t type.
22963
static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
22964
133
                                DSAStackTy *Stack) {
22965
133
  QualType OMPEventHandleT = Stack->getOMPEventHandleT();
22966
133
  if (!OMPEventHandleT.isNull())
22967
114
    return true;
22968
19
  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
22969
19
  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
22970
19
  if (!PT.getAsOpaquePtr() || 
PT.get().isNull()15
) {
22971
4
    S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
22972
4
    return false;
22973
4
  }
22974
15
  Stack->setOMPEventHandleT(PT.get());
22975
15
  return true;
22976
19
}
22977
22978
OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
22979
                                         SourceLocation LParenLoc,
22980
137
                                         SourceLocation EndLoc) {
22981
137
  if (!Evt->isValueDependent() && 
!Evt->isTypeDependent()133
&&
22982
137
      
!Evt->isInstantiationDependent()133
&&
22983
137
      
!Evt->containsUnexpandedParameterPack()133
) {
22984
133
    if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
22985
4
      return nullptr;
22986
    // OpenMP 5.0, 2.10.1 task Construct.
22987
    // event-handle is a variable of the omp_event_handle_t type.
22988
129
    auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
22989
129
    if (!Ref) {
22990
8
      Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22991
8
          << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22992
8
      return nullptr;
22993
8
    }
22994
121
    auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
22995
121
    if (!VD) {
22996
0
      Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22997
0
          << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22998
0
      return nullptr;
22999
0
    }
23000
121
    if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
23001
121
                                        VD->getType()) ||
23002
121
        
VD->getType().isConstant(Context)101
) {
23003
28
      Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23004
28
          << "omp_event_handle_t" << 1 << VD->getType()
23005
28
          << Evt->getSourceRange();
23006
28
      return nullptr;
23007
28
    }
23008
    // OpenMP 5.0, 2.10.1 task Construct
23009
    // [detach clause]... The event-handle will be considered as if it was
23010
    // specified on a firstprivate clause.
23011
93
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
23012
93
    if (DVar.CKind != OMPC_unknown && 
DVar.CKind != OMPC_firstprivate4
&&
23013
93
        
DVar.RefExpr0
) {
23014
0
      Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
23015
0
          << getOpenMPClauseName(DVar.CKind)
23016
0
          << getOpenMPClauseName(OMPC_firstprivate);
23017
0
      reportOriginalDsa(*this, DSAStack, VD, DVar);
23018
0
      return nullptr;
23019
0
    }
23020
93
  }
23021
23022
97
  return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
23023
137
}
23024
23025
OMPClause *Sema::ActOnOpenMPDistScheduleClause(
23026
    OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
23027
    SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
23028
2.23k
    SourceLocation EndLoc) {
23029
2.23k
  if (Kind == OMPC_DIST_SCHEDULE_unknown) {
23030
144
    std::string Values;
23031
144
    Values += "'";
23032
144
    Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
23033
144
    Values += "'";
23034
144
    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23035
144
        << Values << getOpenMPClauseName(OMPC_dist_schedule);
23036
144
    return nullptr;
23037
144
  }
23038
2.09k
  Expr *ValExpr = ChunkSize;
23039
2.09k
  Stmt *HelperValStmt = nullptr;
23040
2.09k
  if (ChunkSize) {
23041
1.38k
    if (!ChunkSize->isValueDependent() && 
!ChunkSize->isTypeDependent()1.15k
&&
23042
1.38k
        
!ChunkSize->isInstantiationDependent()1.15k
&&
23043
1.38k
        
!ChunkSize->containsUnexpandedParameterPack()1.15k
) {
23044
1.15k
      SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
23045
1.15k
      ExprResult Val =
23046
1.15k
          PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
23047
1.15k
      if (Val.isInvalid())
23048
0
        return nullptr;
23049
23050
1.15k
      ValExpr = Val.get();
23051
23052
      // OpenMP [2.7.1, Restrictions]
23053
      //  chunk_size must be a loop invariant integer expression with a positive
23054
      //  value.
23055
1.15k
      if (std::optional<llvm::APSInt> Result =
23056
1.15k
              ValExpr->getIntegerConstantExpr(Context)) {
23057
318
        if (Result->isSigned() && !Result->isStrictlyPositive()) {
23058
0
          Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
23059
0
              << "dist_schedule" << ChunkSize->getSourceRange();
23060
0
          return nullptr;
23061
0
        }
23062
832
      } else if (getOpenMPCaptureRegionForClause(
23063
832
                     DSAStack->getCurrentDirective(), OMPC_dist_schedule,
23064
832
                     LangOpts.OpenMP) != OMPD_unknown &&
23065
832
                 
!CurContext->isDependentContext()344
) {
23066
296
        ValExpr = MakeFullExpr(ValExpr).get();
23067
296
        llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23068
296
        ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
23069
296
        HelperValStmt = buildPreInits(Context, Captures);
23070
296
      }
23071
1.15k
    }
23072
1.38k
  }
23073
23074
2.09k
  return new (Context)
23075
2.09k
      OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
23076
2.09k
                            Kind, ValExpr, HelperValStmt);
23077
2.09k
}
23078
23079
OMPClause *Sema::ActOnOpenMPDefaultmapClause(
23080
    OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
23081
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
23082
3.42k
    SourceLocation KindLoc, SourceLocation EndLoc) {
23083
3.42k
  if (getLangOpts().OpenMP < 50) {
23084
422
    if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
23085
422
        
Kind != OMPC_DEFAULTMAP_scalar302
) {
23086
320
      std::string Value;
23087
320
      SourceLocation Loc;
23088
320
      Value += "'";
23089
320
      if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
23090
120
        Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
23091
120
                                               OMPC_DEFAULTMAP_MODIFIER_tofrom);
23092
120
        Loc = MLoc;
23093
200
      } else {
23094
200
        Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
23095
200
                                               OMPC_DEFAULTMAP_scalar);
23096
200
        Loc = KindLoc;
23097
200
      }
23098
320
      Value += "'";
23099
320
      Diag(Loc, diag::err_omp_unexpected_clause_value)
23100
320
          << Value << getOpenMPClauseName(OMPC_defaultmap);
23101
320
      return nullptr;
23102
320
    }
23103
3.00k
  } else {
23104
3.00k
    bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
23105
3.00k
    bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
23106
3.00k
                            
(948
LangOpts.OpenMP >= 50948
&&
KindLoc.isInvalid()948
);
23107
3.00k
    if (!isDefaultmapKind || 
!isDefaultmapModifier2.83k
) {
23108
324
      StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
23109
324
      if (LangOpts.OpenMP == 50) {
23110
162
        StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
23111
162
                                  "'firstprivate', 'none', 'default'";
23112
162
        if (!isDefaultmapKind && 
isDefaultmapModifier82
) {
23113
42
          Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23114
42
              << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23115
120
        } else if (isDefaultmapKind && 
!isDefaultmapModifier80
) {
23116
80
          Diag(MLoc, diag::err_omp_unexpected_clause_value)
23117
80
              << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23118
80
        } else {
23119
40
          Diag(MLoc, diag::err_omp_unexpected_clause_value)
23120
40
              << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23121
40
          Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23122
40
              << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23123
40
        }
23124
162
      } else {
23125
162
        StringRef ModifierValue =
23126
162
            "'alloc', 'from', 'to', 'tofrom', "
23127
162
            "'firstprivate', 'none', 'default', 'present'";
23128
162
        if (!isDefaultmapKind && 
isDefaultmapModifier82
) {
23129
42
          Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23130
42
              << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23131
120
        } else if (isDefaultmapKind && 
!isDefaultmapModifier80
) {
23132
80
          Diag(MLoc, diag::err_omp_unexpected_clause_value)
23133
80
              << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23134
80
        } else {
23135
40
          Diag(MLoc, diag::err_omp_unexpected_clause_value)
23136
40
              << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23137
40
          Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23138
40
              << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23139
40
        }
23140
162
      }
23141
324
      return nullptr;
23142
324
    }
23143
23144
    // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
23145
    //  At most one defaultmap clause for each category can appear on the
23146
    //  directive.
23147
2.67k
    if (DSAStack->checkDefaultmapCategory(Kind)) {
23148
26
      Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
23149
26
      return nullptr;
23150
26
    }
23151
2.67k
  }
23152
2.75k
  if (Kind == OMPC_DEFAULTMAP_unknown) {
23153
    // Variable category is not specified - mark all categories.
23154
624
    DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
23155
624
    DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
23156
624
    DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
23157
2.12k
  } else {
23158
2.12k
    DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
23159
2.12k
  }
23160
23161
2.75k
  return new (Context)
23162
2.75k
      OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
23163
3.42k
}
23164
23165
bool Sema::ActOnStartOpenMPDeclareTargetContext(
23166
853
    DeclareTargetContextInfo &DTCI) {
23167
853
  DeclContext *CurLexicalContext = getCurLexicalContext();
23168
853
  if (!CurLexicalContext->isFileContext() &&
23169
853
      
!CurLexicalContext->isExternCContext()65
&&
23170
853
      
!CurLexicalContext->isExternCXXContext()51
&&
23171
853
      
!isa<CXXRecordDecl>(CurLexicalContext)37
&&
23172
853
      
!isa<ClassTemplateDecl>(CurLexicalContext)0
&&
23173
853
      
!isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext)0
&&
23174
853
      
!isa<ClassTemplateSpecializationDecl>(CurLexicalContext)0
) {
23175
0
    Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
23176
0
    return false;
23177
0
  }
23178
23179
  // Report affected OpenMP target offloading behavior when in HIP lang-mode.
23180
853
  if (getLangOpts().HIP)
23181
1
    Diag(DTCI.Loc, diag::warn_hip_omp_target_directives);
23182
23183
853
  DeclareTargetNesting.push_back(DTCI);
23184
853
  return true;
23185
853
}
23186
23187
const Sema::DeclareTargetContextInfo
23188
839
Sema::ActOnOpenMPEndDeclareTargetDirective() {
23189
839
  assert(!DeclareTargetNesting.empty() &&
23190
839
         "check isInOpenMPDeclareTargetContext() first!");
23191
839
  return DeclareTargetNesting.pop_back_val();
23192
839
}
23193
23194
void Sema::ActOnFinishedOpenMPDeclareTargetContext(
23195
610
    DeclareTargetContextInfo &DTCI) {
23196
610
  for (auto &It : DTCI.ExplicitlyMapped)
23197
655
    ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
23198
610
}
23199
23200
89.7k
void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() {
23201
89.7k
  if (DeclareTargetNesting.empty())
23202
89.7k
    return;
23203
14
  DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23204
14
  Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
23205
14
      << getOpenMPDirectiveName(DTCI.Kind);
23206
14
}
23207
23208
NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
23209
                                               CXXScopeSpec &ScopeSpec,
23210
723
                                               const DeclarationNameInfo &Id) {
23211
723
  LookupResult Lookup(*this, Id, LookupOrdinaryName);
23212
723
  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
23213
23214
723
  if (Lookup.isAmbiguous())
23215
0
    return nullptr;
23216
723
  Lookup.suppressDiagnostics();
23217
23218
723
  if (!Lookup.isSingleResult()) {
23219
27
    VarOrFuncDeclFilterCCC CCC(*this);
23220
27
    if (TypoCorrection Corrected =
23221
27
            CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
23222
27
                        CTK_ErrorRecovery)) {
23223
0
      diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
23224
0
                                  << Id.getName());
23225
0
      checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
23226
0
      return nullptr;
23227
0
    }
23228
23229
27
    Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
23230
27
    return nullptr;
23231
27
  }
23232
23233
696
  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
23234
696
  if (!isa<VarDecl>(ND) && 
!isa<FunctionDecl>(ND)278
&&
23235
696
      
!isa<FunctionTemplateDecl>(ND)14
) {
23236
14
    Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
23237
14
    return nullptr;
23238
14
  }
23239
682
  return ND;
23240
696
}
23241
23242
void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
23243
                                        OMPDeclareTargetDeclAttr::MapTypeTy MT,
23244
655
                                        DeclareTargetContextInfo &DTCI) {
23245
655
  assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
23246
655
          isa<FunctionTemplateDecl>(ND)) &&
23247
655
         "Expected variable, function or function template.");
23248
23249
  // Diagnose marking after use as it may lead to incorrect diagnosis and
23250
  // codegen.
23251
655
  if (LangOpts.OpenMP >= 50 &&
23252
655
      
(580
ND->isUsed(/*CheckUsedAttr=*/false)580
||
ND->isReferenced()568
))
23253
12
    Diag(Loc, diag::warn_omp_declare_target_after_first_use);
23254
23255
  // Report affected OpenMP target offloading behavior when in HIP lang-mode.
23256
655
  if (getLangOpts().HIP)
23257
1
    Diag(Loc, diag::warn_hip_omp_target_directives);
23258
23259
  // Explicit declare target lists have precedence.
23260
655
  const unsigned Level = -1;
23261
23262
655
  auto *VD = cast<ValueDecl>(ND);
23263
655
  std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23264
655
      OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23265
655
  if (ActiveAttr && 
(*ActiveAttr)->getDevType() != DTCI.DT159
&&
23266
655
      
(*ActiveAttr)->getLevel() == Level78
) {
23267
22
    Diag(Loc, diag::err_omp_device_type_mismatch)
23268
22
        << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
23269
22
        << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
23270
22
               (*ActiveAttr)->getDevType());
23271
22
    return;
23272
22
  }
23273
633
  if (ActiveAttr && 
(*ActiveAttr)->getMapType() != MT137
&&
23274
633
      
(*ActiveAttr)->getLevel() == Level24
) {
23275
14
    Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
23276
14
    return;
23277
14
  }
23278
23279
619
  if (ActiveAttr && 
(*ActiveAttr)->getLevel() == Level123
)
23280
33
    return;
23281
23282
586
  Expr *IndirectE = nullptr;
23283
586
  bool IsIndirect = false;
23284
586
  if (DTCI.Indirect) {
23285
39
    IndirectE = *DTCI.Indirect;
23286
39
    if (!IndirectE)
23287
30
      IsIndirect = true;
23288
39
  }
23289
586
  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23290
586
      Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
23291
586
      SourceRange(Loc, Loc));
23292
586
  ND->addAttr(A);
23293
586
  if (ASTMutationListener *ML = Context.getASTMutationListener())
23294
116
    ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
23295
586
  checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
23296
586
  if (auto *VD = dyn_cast<VarDecl>(ND);
23297
586
      LangOpts.OpenMP && VD && 
VD->hasAttr<OMPDeclareTargetDeclAttr>()338
&&
23298
586
      
VD->hasGlobalStorage()338
)
23299
338
    ActOnOpenMPDeclareTargetInitializer(ND);
23300
586
}
23301
23302
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
23303
2.86k
                                     Sema &SemaRef, Decl *D) {
23304
2.86k
  if (!D || !isa<VarDecl>(D))
23305
2.31k
    return;
23306
547
  auto *VD = cast<VarDecl>(D);
23307
547
  std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
23308
547
      OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
23309
547
  if (SemaRef.LangOpts.OpenMP >= 50 &&
23310
547
      
(443
SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true)443
||
23311
443
       
SemaRef.getCurBlock()403
||
SemaRef.getCurCapturedRegion()403
) &&
23312
547
      
VD->hasGlobalStorage()44
) {
23313
44
    if (!MapTy || 
(32
*MapTy != OMPDeclareTargetDeclAttr::MT_To32
&&
23314
32
                   
*MapTy != OMPDeclareTargetDeclAttr::MT_Enter1
)) {
23315
      // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
23316
      // If a lambda declaration and definition appears between a
23317
      // declare target directive and the matching end declare target
23318
      // directive, all variables that are captured by the lambda
23319
      // expression must also appear in a to clause.
23320
12
      SemaRef.Diag(VD->getLocation(),
23321
12
                   diag::err_omp_lambda_capture_in_declare_target_not_to);
23322
12
      SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
23323
12
          << VD << 0 << SR;
23324
12
      return;
23325
12
    }
23326
44
  }
23327
535
  if (MapTy)
23328
428
    return;
23329
107
  SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
23330
107
  SemaRef.Diag(SL, diag::note_used_here) << SR;
23331
107
}
23332
23333
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
23334
                                   Sema &SemaRef, DSAStackTy *Stack,
23335
7.60k
                                   ValueDecl *VD) {
23336
7.60k
  return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
23337
7.60k
         checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
23338
4.75k
                           /*FullCheck=*/false);
23339
7.60k
}
23340
23341
void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
23342
10.0k
                                            SourceLocation IdLoc) {
23343
10.0k
  if (!D || D->isInvalidDecl())
23344
2
    return;
23345
10.0k
  SourceRange SR = E ? 
E->getSourceRange()4.87k
:
D->getSourceRange()5.17k
;
23346
10.0k
  SourceLocation SL = E ? 
E->getBeginLoc()4.87k
:
D->getLocation()5.17k
;
23347
10.0k
  if (auto *VD = dyn_cast<VarDecl>(D)) {
23348
    // Only global variables can be marked as declare target.
23349
4.08k
    if (!VD->isFileVarDecl() && 
!VD->isStaticLocal()2.37k
&&
23350
4.08k
        
!VD->isStaticDataMember()2.36k
)
23351
2.36k
      return;
23352
    // 2.10.6: threadprivate variable cannot appear in a declare target
23353
    // directive.
23354
1.72k
    if (DSAStack->isThreadPrivate(VD)) {
23355
28
      Diag(SL, diag::err_omp_threadprivate_in_target);
23356
28
      reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
23357
28
      return;
23358
28
    }
23359
1.72k
  }
23360
7.64k
  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
23361
32
    D = FTD->getTemplatedDecl();
23362
7.64k
  if (auto *FD = dyn_cast<FunctionDecl>(D)) {
23363
5.80k
    std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
23364
5.80k
        OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
23365
5.80k
    if (IdLoc.isValid() && 
Res248
&&
*Res == OMPDeclareTargetDeclAttr::MT_Link248
) {
23366
14
      Diag(IdLoc, diag::err_omp_function_in_link_clause);
23367
14
      Diag(FD->getLocation(), diag::note_defined_here) << FD;
23368
14
      return;
23369
14
    }
23370
5.80k
  }
23371
7.63k
  if (auto *VD = dyn_cast<ValueDecl>(D)) {
23372
    // Problem if any with var declared with incomplete type will be reported
23373
    // as normal, so no need to check it here.
23374
7.61k
    if ((E || 
!VD->getType()->isIncompleteType()4.74k
) &&
23375
7.61k
        
!checkValueDeclInTarget(SL, SR, *this, 7.60k
DSAStack7.60k
, VD))
23376
0
      return;
23377
7.61k
    if (!E && 
isInOpenMPDeclareTargetContext()4.74k
) {
23378
      // Checking declaration inside declare target region.
23379
4.19k
      if (isa<VarDecl>(D) || 
isa<FunctionDecl>(D)3.37k
||
23380
4.19k
          
isa<FunctionTemplateDecl>(D)0
) {
23381
4.19k
        std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23382
4.19k
            OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23383
4.19k
        unsigned Level = DeclareTargetNesting.size();
23384
4.19k
        if (ActiveAttr && 
(*ActiveAttr)->getLevel() >= Level390
)
23385
390
          return;
23386
3.80k
        DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23387
3.80k
        Expr *IndirectE = nullptr;
23388
3.80k
        bool IsIndirect = false;
23389
3.80k
        if (DTCI.Indirect) {
23390
19
          IndirectE = *DTCI.Indirect;
23391
19
          if (!IndirectE)
23392
9
            IsIndirect = true;
23393
19
        }
23394
3.80k
        auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23395
3.80k
            Context,
23396
3.80k
            getLangOpts().OpenMP >= 52 ? 
OMPDeclareTargetDeclAttr::MT_Enter72
23397
3.80k
                                       : 
OMPDeclareTargetDeclAttr::MT_To3.73k
,
23398
3.80k
            DTCI.DT, IndirectE, IsIndirect, Level,
23399
3.80k
            SourceRange(DTCI.Loc, DTCI.Loc));
23400
3.80k
        D->addAttr(A);
23401
3.80k
        if (ASTMutationListener *ML = Context.getASTMutationListener())
23402
1.13k
          ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
23403
3.80k
      }
23404
3.80k
      return;
23405
4.19k
    }
23406
7.61k
  }
23407
3.43k
  if (!E)
23408
577
    return;
23409
2.86k
  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
23410
2.86k
}
23411
23412
/// This class visits every VarDecl that the initializer references and adds
23413
/// OMPDeclareTargetDeclAttr to each of them.
23414
class GlobalDeclRefChecker final
23415
    : public StmtVisitor<GlobalDeclRefChecker> {
23416
  SmallVector<VarDecl *> DeclVector;
23417
  Attr *A;
23418
23419
public:
23420
  /// A StmtVisitor class function that visits all DeclRefExpr and adds
23421
  /// OMPDeclareTargetDeclAttr to them.
23422
338
  void VisitDeclRefExpr(DeclRefExpr *Node) {
23423
338
    if (auto *VD = dyn_cast<VarDecl>(Node->getDecl())) {
23424
238
      VD->addAttr(A);
23425
238
      DeclVector.push_back(VD);
23426
238
    }
23427
338
  }
23428
  /// A function that iterates across each of the Expr's children.
23429
1.10k
  void VisitExpr(Expr *Ex) {
23430
1.10k
    for (auto *Child : Ex->children()) {
23431
749
      Visit(Child);
23432
749
    }
23433
1.10k
  }
23434
  /// A function that keeps a record of all the Decls that are variables, has
23435
  /// OMPDeclareTargetDeclAttr, and has global storage in the DeclVector. Pop
23436
  /// each Decl one at a time and use the inherited 'visit' functions to look
23437
  /// for DeclRefExpr.
23438
1.13k
  void declareTargetInitializer(Decl *TD) {
23439
1.13k
    A = TD->getAttr<OMPDeclareTargetDeclAttr>();
23440
1.13k
    DeclVector.push_back(cast<VarDecl>(TD));
23441
2.50k
    while (!DeclVector.empty()) {
23442
1.37k
      VarDecl *TargetVarDecl = DeclVector.pop_back_val();
23443
1.37k
      if (TargetVarDecl->hasAttr<OMPDeclareTargetDeclAttr>() &&
23444
1.37k
          TargetVarDecl->hasInit() && 
TargetVarDecl->hasGlobalStorage()690
) {
23445
690
        if (Expr *Ex = TargetVarDecl->getInit())
23446
690
          Visit(Ex);
23447
690
      }
23448
1.37k
    }
23449
1.13k
  }
23450
};
23451
23452
/// Adding OMPDeclareTargetDeclAttr to variables with static storage
23453
/// duration that are referenced in the initializer expression list of
23454
/// variables with static storage duration in declare target directive.
23455
1.13k
void Sema::ActOnOpenMPDeclareTargetInitializer(Decl *TargetDecl) {
23456
1.13k
  GlobalDeclRefChecker Checker;
23457
1.13k
  if (isa<VarDecl>(TargetDecl))
23458
1.13k
    Checker.declareTargetInitializer(TargetDecl);
23459
1.13k
}
23460
23461
OMPClause *Sema::ActOnOpenMPToClause(
23462
    ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23463
    ArrayRef<SourceLocation> MotionModifiersLoc,
23464
    CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23465
    SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23466
3.05k
    const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23467
3.05k
  OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23468
3.05k
                                          OMPC_MOTION_MODIFIER_unknown};
23469
3.05k
  SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23470
23471
  // Process motion-modifiers, flag errors for duplicate modifiers.
23472
3.05k
  unsigned Count = 0;
23473
4.95k
  for (unsigned I = 0, E = MotionModifiers.size(); I < E; 
++I1.90k
) {
23474
1.90k
    if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23475
1.90k
        
llvm::is_contained(Modifiers, MotionModifiers[I])242
) {
23476
0
      Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23477
0
      continue;
23478
0
    }
23479
1.90k
    assert(Count < NumberOfOMPMotionModifiers &&
23480
1.90k
           "Modifiers exceed the allowed number of motion modifiers");
23481
1.90k
    Modifiers[Count] = MotionModifiers[I];
23482
1.90k
    ModifiersLoc[Count] = MotionModifiersLoc[I];
23483
1.90k
    ++Count;
23484
1.90k
  }
23485
23486
3.05k
  MappableVarListInfo MVLI(VarList);
23487
3.05k
  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
23488
3.05k
                              MapperIdScopeSpec, MapperId, UnresolvedMappers);
23489
3.05k
  if (MVLI.ProcessedVarList.empty())
23490
175
    return nullptr;
23491
23492
2.87k
  return OMPToClause::Create(
23493
2.87k
      Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23494
2.87k
      MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23495
2.87k
      MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23496
3.05k
}
23497
23498
OMPClause *Sema::ActOnOpenMPFromClause(
23499
    ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23500
    ArrayRef<SourceLocation> MotionModifiersLoc,
23501
    CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23502
    SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23503
1.47k
    const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23504
1.47k
  OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23505
1.47k
                                          OMPC_MOTION_MODIFIER_unknown};
23506
1.47k
  SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23507
23508
  // Process motion-modifiers, flag errors for duplicate modifiers.
23509
1.47k
  unsigned Count = 0;
23510
2.58k
  for (unsigned I = 0, E = MotionModifiers.size(); I < E; 
++I1.11k
) {
23511
1.11k
    if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23512
1.11k
        
llvm::is_contained(Modifiers, MotionModifiers[I])168
) {
23513
0
      Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23514
0
      continue;
23515
0
    }
23516
1.11k
    assert(Count < NumberOfOMPMotionModifiers &&
23517
1.11k
           "Modifiers exceed the allowed number of motion modifiers");
23518
1.11k
    Modifiers[Count] = MotionModifiers[I];
23519
1.11k
    ModifiersLoc[Count] = MotionModifiersLoc[I];
23520
1.11k
    ++Count;
23521
1.11k
  }
23522
23523
1.47k
  MappableVarListInfo MVLI(VarList);
23524
1.47k
  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
23525
1.47k
                              MapperIdScopeSpec, MapperId, UnresolvedMappers);
23526
1.47k
  if (MVLI.ProcessedVarList.empty())
23527
134
    return nullptr;
23528
23529
1.33k
  return OMPFromClause::Create(
23530
1.33k
      Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23531
1.33k
      MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23532
1.33k
      MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23533
1.47k
}
23534
23535
OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
23536
540
                                               const OMPVarListLocTy &Locs) {
23537
540
  MappableVarListInfo MVLI(VarList);
23538
540
  SmallVector<Expr *, 8> PrivateCopies;
23539
540
  SmallVector<Expr *, 8> Inits;
23540
23541
604
  for (Expr *RefExpr : VarList) {
23542
604
    assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
23543
604
    SourceLocation ELoc;
23544
604
    SourceRange ERange;
23545
604
    Expr *SimpleRefExpr = RefExpr;
23546
604
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23547
604
    if (Res.second) {
23548
      // It will be analyzed later.
23549
144
      MVLI.ProcessedVarList.push_back(RefExpr);
23550
144
      PrivateCopies.push_back(nullptr);
23551
144
      Inits.push_back(nullptr);
23552
144
    }
23553
604
    ValueDecl *D = Res.first;
23554
604
    if (!D)
23555
144
      continue;
23556
23557
460
    QualType Type = D->getType();
23558
460
    Type = Type.getNonReferenceType().getUnqualifiedType();
23559
23560
460
    auto *VD = dyn_cast<VarDecl>(D);
23561
23562
    // Item should be a pointer or reference to pointer.
23563
460
    if (!Type->isPointerType()) {
23564
120
      Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23565
120
          << 0 << RefExpr->getSourceRange();
23566
120
      continue;
23567
120
    }
23568
23569
    // Build the private variable and the expression that refers to it.
23570
340
    auto VDPrivate =
23571
340
        buildVarDecl(*this, ELoc, Type, D->getName(),
23572
340
                     D->hasAttrs() ? 
&D->getAttrs()0
: nullptr,
23573
340
                     VD ? 
cast<DeclRefExpr>(SimpleRefExpr)272
:
nullptr68
);
23574
340
    if (VDPrivate->isInvalidDecl())
23575
0
      continue;
23576
23577
340
    CurContext->addDecl(VDPrivate);
23578
340
    DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
23579
340
        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23580
23581
    // Add temporary variable to initialize the private copy of the pointer.
23582
340
    VarDecl *VDInit =
23583
340
        buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
23584
340
    DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
23585
340
        *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
23586
340
    AddInitializerToDecl(VDPrivate,
23587
340
                         DefaultLvalueConversion(VDInitRefExpr).get(),
23588
340
                         /*DirectInit=*/false);
23589
23590
    // If required, build a capture to implement the privatization initialized
23591
    // with the current list item value.
23592
340
    DeclRefExpr *Ref = nullptr;
23593
340
    if (!VD)
23594
68
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23595
340
    MVLI.ProcessedVarList.push_back(VD ? 
RefExpr->IgnoreParens()272
:
Ref68
);
23596
340
    PrivateCopies.push_back(VDPrivateRefExpr);
23597
340
    Inits.push_back(VDInitRefExpr);
23598
23599
    // We need to add a data sharing attribute for this variable to make sure it
23600
    // is correctly captured. A variable that shows up in a use_device_ptr has
23601
    // similar properties of a first private variable.
23602
340
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23603
23604
    // Create a mappable component for the list item. List items in this clause
23605
    // only need a component.
23606
340
    MVLI.VarBaseDeclarations.push_back(D);
23607
340
    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23608
340
    MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
23609
340
                                           /*IsNonContiguous=*/false);
23610
340
  }
23611
23612
540
  if (MVLI.ProcessedVarList.empty())
23613
96
    return nullptr;
23614
23615
444
  return OMPUseDevicePtrClause::Create(
23616
444
      Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
23617
444
      MVLI.VarBaseDeclarations, MVLI.VarComponents);
23618
540
}
23619
23620
OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
23621
122
                                                const OMPVarListLocTy &Locs) {
23622
122
  MappableVarListInfo MVLI(VarList);
23623
23624
194
  for (Expr *RefExpr : VarList) {
23625
194
    assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
23626
194
    SourceLocation ELoc;
23627
194
    SourceRange ERange;
23628
194
    Expr *SimpleRefExpr = RefExpr;
23629
194
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23630
194
                              /*AllowArraySection=*/true);
23631
194
    if (Res.second) {
23632
      // It will be analyzed later.
23633
22
      MVLI.ProcessedVarList.push_back(RefExpr);
23634
22
    }
23635
194
    ValueDecl *D = Res.first;
23636
194
    if (!D)
23637
22
      continue;
23638
172
    auto *VD = dyn_cast<VarDecl>(D);
23639
23640
    // If required, build a capture to implement the privatization initialized
23641
    // with the current list item value.
23642
172
    DeclRefExpr *Ref = nullptr;
23643
172
    if (!VD)
23644
60
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23645
172
    MVLI.ProcessedVarList.push_back(VD ? 
RefExpr->IgnoreParens()112
:
Ref60
);
23646
23647
    // We need to add a data sharing attribute for this variable to make sure it
23648
    // is correctly captured. A variable that shows up in a use_device_addr has
23649
    // similar properties of a first private variable.
23650
172
    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23651
23652
    // Create a mappable component for the list item. List items in this clause
23653
    // only need a component.
23654
172
    MVLI.VarBaseDeclarations.push_back(D);
23655
172
    MVLI.VarComponents.emplace_back();
23656
172
    Expr *Component = SimpleRefExpr;
23657
172
    if (VD && 
(112
isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts())112
||
23658
112
               
isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())96
))
23659
26
      Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23660
172
    MVLI.VarComponents.back().emplace_back(Component, D,
23661
172
                                           /*IsNonContiguous=*/false);
23662
172
  }
23663
23664
122
  if (MVLI.ProcessedVarList.empty())
23665
0
    return nullptr;
23666
23667
122
  return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23668
122
                                        MVLI.VarBaseDeclarations,
23669
122
                                        MVLI.VarComponents);
23670
122
}
23671
23672
OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
23673
3.84k
                                              const OMPVarListLocTy &Locs) {
23674
3.84k
  MappableVarListInfo MVLI(VarList);
23675
4.17k
  for (Expr *RefExpr : VarList) {
23676
4.17k
    assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
23677
4.17k
    SourceLocation ELoc;
23678
4.17k
    SourceRange ERange;
23679
4.17k
    Expr *SimpleRefExpr = RefExpr;
23680
4.17k
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23681
4.17k
    if (Res.second) {
23682
      // It will be analyzed later.
23683
656
      MVLI.ProcessedVarList.push_back(RefExpr);
23684
656
    }
23685
4.17k
    ValueDecl *D = Res.first;
23686
4.17k
    if (!D)
23687
656
      continue;
23688
23689
3.52k
    QualType Type = D->getType();
23690
    // item should be a pointer or array or reference to pointer or array
23691
3.52k
    if (!Type.getNonReferenceType()->isPointerType() &&
23692
3.52k
        
!Type.getNonReferenceType()->isArrayType()1.98k
) {
23693
736
      Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23694
736
          << 0 << RefExpr->getSourceRange();
23695
736
      continue;
23696
736
    }
23697
23698
    // Check if the declaration in the clause does not show up in any data
23699
    // sharing attribute.
23700
2.78k
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23701
2.78k
    if (isOpenMPPrivate(DVar.CKind)) {
23702
116
      Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23703
116
          << getOpenMPClauseName(DVar.CKind)
23704
116
          << getOpenMPClauseName(OMPC_is_device_ptr)
23705
116
          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23706
116
      reportOriginalDsa(*this, DSAStack, D, DVar);
23707
116
      continue;
23708
116
    }
23709
23710
2.67k
    const Expr *ConflictExpr;
23711
2.67k
    if (DSAStack->checkMappableExprComponentListsForDecl(
23712
2.67k
            D, /*CurrentRegionOnly=*/true,
23713
2.67k
            [&ConflictExpr](
23714
2.67k
                OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23715
2.67k
                OpenMPClauseKind) -> bool {
23716
116
              ConflictExpr = R.front().getAssociatedExpression();
23717
116
              return true;
23718
116
            })) {
23719
116
      Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23720
116
      Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23721
116
          << ConflictExpr->getSourceRange();
23722
116
      continue;
23723
116
    }
23724
23725
    // Store the components in the stack so that they can be used to check
23726
    // against other clauses later on.
23727
2.55k
    OMPClauseMappableExprCommon::MappableComponent MC(
23728
2.55k
        SimpleRefExpr, D, /*IsNonContiguous=*/false);
23729
2.55k
    DSAStack->addMappableExpressionComponents(
23730
2.55k
        D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
23731
23732
    // Record the expression we've just processed.
23733
2.55k
    MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23734
23735
    // Create a mappable component for the list item. List items in this clause
23736
    // only need a component. We use a null declaration to signal fields in
23737
    // 'this'.
23738
2.55k
    assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23739
2.55k
            isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23740
2.55k
           "Unexpected device pointer expression!");
23741
2.55k
    MVLI.VarBaseDeclarations.push_back(
23742
2.55k
        isa<DeclRefExpr>(SimpleRefExpr) ? 
D2.03k
:
nullptr516
);
23743
2.55k
    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23744
2.55k
    MVLI.VarComponents.back().push_back(MC);
23745
2.55k
  }
23746
23747
3.84k
  if (MVLI.ProcessedVarList.empty())
23748
776
    return nullptr;
23749
23750
3.06k
  return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23751
3.06k
                                      MVLI.VarBaseDeclarations,
23752
3.06k
                                      MVLI.VarComponents);
23753
3.84k
}
23754
23755
OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
23756
366
                                                const OMPVarListLocTy &Locs) {
23757
366
  MappableVarListInfo MVLI(VarList);
23758
396
  for (Expr *RefExpr : VarList) {
23759
396
    assert(RefExpr && "NULL expr in OpenMP has_device_addr clause.");
23760
396
    SourceLocation ELoc;
23761
396
    SourceRange ERange;
23762
396
    Expr *SimpleRefExpr = RefExpr;
23763
396
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23764
396
                              /*AllowArraySection=*/true);
23765
396
    if (Res.second) {
23766
      // It will be analyzed later.
23767
50
      MVLI.ProcessedVarList.push_back(RefExpr);
23768
50
    }
23769
396
    ValueDecl *D = Res.first;
23770
396
    if (!D)
23771
50
      continue;
23772
23773
    // Check if the declaration in the clause does not show up in any data
23774
    // sharing attribute.
23775
346
    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23776
346
    if (isOpenMPPrivate(DVar.CKind)) {
23777
8
      Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23778
8
          << getOpenMPClauseName(DVar.CKind)
23779
8
          << getOpenMPClauseName(OMPC_has_device_addr)
23780
8
          << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23781
8
      reportOriginalDsa(*this, DSAStack, D, DVar);
23782
8
      continue;
23783
8
    }
23784
23785
338
    const Expr *ConflictExpr;
23786
338
    if (DSAStack->checkMappableExprComponentListsForDecl(
23787
338
            D, /*CurrentRegionOnly=*/true,
23788
338
            [&ConflictExpr](
23789
338
                OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23790
338
                OpenMPClauseKind) -> bool {
23791
8
              ConflictExpr = R.front().getAssociatedExpression();
23792
8
              return true;
23793
8
            })) {
23794
8
      Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23795
8
      Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23796
8
          << ConflictExpr->getSourceRange();
23797
8
      continue;
23798
8
    }
23799
23800
    // Store the components in the stack so that they can be used to check
23801
    // against other clauses later on.
23802
330
    Expr *Component = SimpleRefExpr;
23803
330
    auto *VD = dyn_cast<VarDecl>(D);
23804
330
    if (VD && 
(240
isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts())240
||
23805
240
               
isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())230
))
23806
14
      Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23807
330
    OMPClauseMappableExprCommon::MappableComponent MC(
23808
330
        Component, D, /*IsNonContiguous=*/false);
23809
330
    DSAStack->addMappableExpressionComponents(
23810
330
        D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
23811
23812
    // Record the expression we've just processed.
23813
330
    if (!VD && 
!CurContext->isDependentContext()90
) {
23814
83
      DeclRefExpr *Ref =
23815
83
          buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23816
83
      assert(Ref && "has_device_addr capture failed");
23817
83
      MVLI.ProcessedVarList.push_back(Ref);
23818
83
    } else
23819
247
      MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23820
23821
    // Create a mappable component for the list item. List items in this clause
23822
    // only need a component. We use a null declaration to signal fields in
23823
    // 'this'.
23824
330
    assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23825
330
            isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23826
330
           "Unexpected device pointer expression!");
23827
330
    MVLI.VarBaseDeclarations.push_back(
23828
330
        isa<DeclRefExpr>(SimpleRefExpr) ? 
D240
:
nullptr90
);
23829
330
    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23830
330
    MVLI.VarComponents.back().push_back(MC);
23831
330
  }
23832
23833
366
  if (MVLI.ProcessedVarList.empty())
23834
16
    return nullptr;
23835
23836
350
  return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23837
350
                                        MVLI.VarBaseDeclarations,
23838
350
                                        MVLI.VarComponents);
23839
366
}
23840
23841
OMPClause *Sema::ActOnOpenMPAllocateClause(
23842
    Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23843
3.38k
    SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
23844
3.38k
  if (Allocator) {
23845
    // OpenMP [2.11.4 allocate Clause, Description]
23846
    // allocator is an expression of omp_allocator_handle_t type.
23847
2.10k
    if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
23848
0
      return nullptr;
23849
23850
2.10k
    ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
23851
2.10k
    if (AllocatorRes.isInvalid())
23852
0
      return nullptr;
23853
2.10k
    AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
23854
2.10k
                                             DSAStack->getOMPAllocatorHandleT(),
23855
2.10k
                                             Sema::AA_Initializing,
23856
2.10k
                                             /*AllowExplicit=*/true);
23857
2.10k
    if (AllocatorRes.isInvalid())
23858
0
      return nullptr;
23859
2.10k
    Allocator = AllocatorRes.get();
23860
2.10k
  } else {
23861
    // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23862
    // allocate clauses that appear on a target construct or on constructs in a
23863
    // target region must specify an allocator expression unless a requires
23864
    // directive with the dynamic_allocators clause is present in the same
23865
    // compilation unit.
23866
1.27k
    if (LangOpts.OpenMPIsTargetDevice &&
23867
1.27k
        
!4
DSAStack4
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
23868
2
      targetDiag(StartLoc, diag::err_expected_allocator_expression);
23869
1.27k
  }
23870
  // Analyze and build list of variables.
23871
3.38k
  SmallVector<Expr *, 8> Vars;
23872
3.38k
  for (Expr *RefExpr : VarList) {
23873
3.38k
    assert(RefExpr && "NULL expr in OpenMP private clause.");
23874
3.38k
    SourceLocation ELoc;
23875
3.38k
    SourceRange ERange;
23876
3.38k
    Expr *SimpleRefExpr = RefExpr;
23877
3.38k
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23878
3.38k
    if (Res.second) {
23879
      // It will be analyzed later.
23880
1.02k
      Vars.push_back(RefExpr);
23881
1.02k
    }
23882
3.38k
    ValueDecl *D = Res.first;
23883
3.38k
    if (!D)
23884
1.02k
      continue;
23885
23886
2.35k
    auto *VD = dyn_cast<VarDecl>(D);
23887
2.35k
    DeclRefExpr *Ref = nullptr;
23888
2.35k
    if (!VD && 
!CurContext->isDependentContext()66
)
23889
66
      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
23890
2.35k
    Vars.push_back((VD || 
CurContext->isDependentContext()66
)
23891
2.35k
                       ? 
RefExpr->IgnoreParens()2.28k
23892
2.35k
                       : 
Ref66
);
23893
2.35k
  }
23894
23895
3.38k
  if (Vars.empty())
23896
0
    return nullptr;
23897
23898
3.38k
  if (Allocator)
23899
2.10k
    DSAStack->addInnerAllocatorExpr(Allocator);
23900
3.38k
  return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
23901
3.38k
                                   ColonLoc, EndLoc, Vars);
23902
3.38k
}
23903
23904
OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
23905
                                              SourceLocation StartLoc,
23906
                                              SourceLocation LParenLoc,
23907
754
                                              SourceLocation EndLoc) {
23908
754
  SmallVector<Expr *, 8> Vars;
23909
1.14k
  for (Expr *RefExpr : VarList) {
23910
1.14k
    assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23911
1.14k
    SourceLocation ELoc;
23912
1.14k
    SourceRange ERange;
23913
1.14k
    Expr *SimpleRefExpr = RefExpr;
23914
1.14k
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23915
1.14k
    if (Res.second)
23916
      // It will be analyzed later.
23917
112
      Vars.push_back(RefExpr);
23918
1.14k
    ValueDecl *D = Res.first;
23919
1.14k
    if (!D)
23920
158
      continue;
23921
23922
    // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23923
    // A list-item cannot appear in more than one nontemporal clause.
23924
982
    if (const Expr *PrevRef =
23925
982
            DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
23926
46
      Diag(ELoc, diag::err_omp_used_in_clause_twice)
23927
46
          << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
23928
46
      Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
23929
46
          << getOpenMPClauseName(OMPC_nontemporal);
23930
46
      continue;
23931
46
    }
23932
23933
936
    Vars.push_back(RefExpr);
23934
936
  }
23935
23936
754
  if (Vars.empty())
23937
92
    return nullptr;
23938
23939
662
  return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23940
662
                                      Vars);
23941
754
}
23942
23943
StmtResult Sema::ActOnOpenMPScopeDirective(ArrayRef<OMPClause *> Clauses,
23944
                                           Stmt *AStmt, SourceLocation StartLoc,
23945
1.16k
                                           SourceLocation EndLoc) {
23946
1.16k
  if (!AStmt)
23947
18
    return StmtError();
23948
23949
1.14k
  setFunctionHasBranchProtectedScope();
23950
23951
1.14k
  return OMPScopeDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
23952
1.16k
}
23953
23954
OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
23955
                                            SourceLocation StartLoc,
23956
                                            SourceLocation LParenLoc,
23957
134
                                            SourceLocation EndLoc) {
23958
134
  SmallVector<Expr *, 8> Vars;
23959
150
  for (Expr *RefExpr : VarList) {
23960
150
    assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23961
150
    SourceLocation ELoc;
23962
150
    SourceRange ERange;
23963
150
    Expr *SimpleRefExpr = RefExpr;
23964
150
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23965
150
                              /*AllowArraySection=*/true);
23966
150
    if (Res.second)
23967
      // It will be analyzed later.
23968
28
      Vars.push_back(RefExpr);
23969
150
    ValueDecl *D = Res.first;
23970
150
    if (!D)
23971
28
      continue;
23972
23973
122
    const DSAStackTy::DSAVarData DVar =
23974
122
        DSAStack->getTopDSA(D, /*FromParent=*/true);
23975
    // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23976
    // A list item that appears in the inclusive or exclusive clause must appear
23977
    // in a reduction clause with the inscan modifier on the enclosing
23978
    // worksharing-loop, worksharing-loop SIMD, or simd construct.
23979
122
    if (DVar.CKind != OMPC_reduction || 
DVar.Modifier != OMPC_REDUCTION_inscan116
)
23980
6
      Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23981
6
          << RefExpr->getSourceRange();
23982
23983
122
    if (DSAStack->getParentDirective() != OMPD_unknown)
23984
116
      DSAStack->markDeclAsUsedInScanDirective(D);
23985
122
    Vars.push_back(RefExpr);
23986
122
  }
23987
23988
134
  if (Vars.empty())
23989
0
    return nullptr;
23990
23991
134
  return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
23992
134
}
23993
23994
OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
23995
                                            SourceLocation StartLoc,
23996
                                            SourceLocation LParenLoc,
23997
115
                                            SourceLocation EndLoc) {
23998
115
  SmallVector<Expr *, 8> Vars;
23999
135
  for (Expr *RefExpr : VarList) {
24000
135
    assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
24001
135
    SourceLocation ELoc;
24002
135
    SourceRange ERange;
24003
135
    Expr *SimpleRefExpr = RefExpr;
24004
135
    auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
24005
135
                              /*AllowArraySection=*/true);
24006
135
    if (Res.second)
24007
      // It will be analyzed later.
24008
12
      Vars.push_back(RefExpr);
24009
135
    ValueDecl *D = Res.first;
24010
135
    if (!D)
24011
12
      continue;
24012
24013
123
    OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
24014
123
    DSAStackTy::DSAVarData DVar;
24015
123
    if (ParentDirective != OMPD_unknown)
24016
119
      DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
24017
    // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
24018
    // A list item that appears in the inclusive or exclusive clause must appear
24019
    // in a reduction clause with the inscan modifier on the enclosing
24020
    // worksharing-loop, worksharing-loop SIMD, or simd construct.
24021
123
    if (ParentDirective == OMPD_unknown || 
DVar.CKind != OMPC_reduction119
||
24022
123
        
DVar.Modifier != OMPC_REDUCTION_inscan119
) {
24023
4
      Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24024
4
          << RefExpr->getSourceRange();
24025
119
    } else {
24026
119
      DSAStack->markDeclAsUsedInScanDirective(D);
24027
119
    }
24028
123
    Vars.push_back(RefExpr);
24029
123
  }
24030
24031
115
  if (Vars.empty())
24032
0
    return nullptr;
24033
24034
115
  return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
24035
115
}
24036
24037
/// Tries to find omp_alloctrait_t type.
24038
52
static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
24039
52
  QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
24040
52
  if (!OMPAlloctraitT.isNull())
24041
17
    return true;
24042
35
  IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
24043
35
  ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
24044
35
  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
24045
0
    S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
24046
0
    return false;
24047
0
  }
24048
35
  Stack->setOMPAlloctraitT(PT.get());
24049
35
  return true;
24050
35
}
24051
24052
OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
24053
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
24054
435
    ArrayRef<UsesAllocatorsData> Data) {
24055
  // OpenMP [2.12.5, target Construct]
24056
  // allocator is an identifier of omp_allocator_handle_t type.
24057
435
  if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
24058
0
    return nullptr;
24059
  // OpenMP [2.12.5, target Construct]
24060
  // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
24061
435
  if (llvm::any_of(
24062
435
          Data,
24063
509
          [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
24064
435
      
!findOMPAlloctraitT(*this, StartLoc, 52
DSAStack52
))
24065
0
    return nullptr;
24066
435
  llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
24067
4.35k
  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 
++I3.91k
) {
24068
3.91k
    auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
24069
3.91k
    StringRef Allocator =
24070
3.91k
        OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
24071
3.91k
    DeclarationName AllocatorName = &Context.Idents.get(Allocator);
24072
3.91k
    PredefinedAllocators.insert(LookupSingleName(
24073
3.91k
        TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
24074
3.91k
  }
24075
24076
435
  SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
24077
523
  for (const UsesAllocatorsData &D : Data) {
24078
523
    Expr *AllocatorExpr = nullptr;
24079
    // Check allocator expression.
24080
523
    if (D.Allocator->isTypeDependent()) {
24081
0
      AllocatorExpr = D.Allocator;
24082
523
    } else {
24083
      // Traits were specified - need to assign new allocator to the specified
24084
      // allocator, so it must be an lvalue.
24085
523
      AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
24086
523
      auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
24087
523
      bool IsPredefinedAllocator = false;
24088
523
      if (DRE) {
24089
523
        OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
24090
523
            getAllocatorKind(*this, DSAStack, AllocatorExpr);
24091
523
        IsPredefinedAllocator =
24092
523
            AllocatorTy !=
24093
523
            OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
24094
523
      }
24095
523
      QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT();
24096
523
      QualType AllocatorExprType = AllocatorExpr->getType();
24097
523
      bool IsTypeCompatible = IsPredefinedAllocator;
24098
523
      IsTypeCompatible = IsTypeCompatible ||
24099
523
                         Context.hasSameUnqualifiedType(AllocatorExprType,
24100
62
                                                        OMPAllocatorHandleT);
24101
523
      IsTypeCompatible =
24102
523
          IsTypeCompatible ||
24103
523
          
Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT)4
;
24104
523
      bool IsNonConstantLValue =
24105
523
          !AllocatorExprType.isConstant(Context) && 
AllocatorExpr->isLValue()141
;
24106
523
      if (!DRE || !IsTypeCompatible ||
24107
523
          
(519
!IsPredefinedAllocator519
&&
!IsNonConstantLValue58
)) {
24108
6
        Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
24109
6
            << "omp_allocator_handle_t" << (DRE ? 1 : 
00
)
24110
6
            << AllocatorExpr->getType() << D.Allocator->getSourceRange();
24111
6
        continue;
24112
6
      }
24113
      // OpenMP [2.12.5, target Construct]
24114
      // Predefined allocators appearing in a uses_allocators clause cannot have
24115
      // traits specified.
24116
517
      if (IsPredefinedAllocator && 
D.AllocatorTraits461
) {
24117
16
        Diag(D.AllocatorTraits->getExprLoc(),
24118
16
             diag::err_omp_predefined_allocator_with_traits)
24119
16
            << D.AllocatorTraits->getSourceRange();
24120
16
        Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
24121
16
            << cast<NamedDecl>(DRE->getDecl())->getName()
24122
16
            << D.Allocator->getSourceRange();
24123
16
        continue;
24124
16
      }
24125
      // OpenMP [2.12.5, target Construct]
24126
      // Non-predefined allocators appearing in a uses_allocators clause must
24127
      // have traits specified.
24128
501
      if (!IsPredefinedAllocator && 
!D.AllocatorTraits56
) {
24129
6
        Diag(D.Allocator->getExprLoc(),
24130
6
             diag::err_omp_nonpredefined_allocator_without_traits);
24131
6
        continue;
24132
6
      }
24133
      // No allocator traits - just convert it to rvalue.
24134
495
      if (!D.AllocatorTraits)
24135
445
        AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
24136
495
      DSAStack->addUsesAllocatorsDecl(
24137
495
          DRE->getDecl(),
24138
495
          IsPredefinedAllocator
24139
495
              ? 
DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator445
24140
495
              : 
DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator50
);
24141
495
    }
24142
495
    Expr *AllocatorTraitsExpr = nullptr;
24143
495
    if (D.AllocatorTraits) {
24144
50
      if (D.AllocatorTraits->isTypeDependent()) {
24145
0
        AllocatorTraitsExpr = D.AllocatorTraits;
24146
50
      } else {
24147
        // OpenMP [2.12.5, target Construct]
24148
        // Arrays that contain allocator traits that appear in a uses_allocators
24149
        // clause must be constant arrays, have constant values and be defined
24150
        // in the same scope as the construct in which the clause appears.
24151
50
        AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
24152
        // Check that traits expr is a constant array.
24153
50
        QualType TraitTy;
24154
50
        if (const ArrayType *Ty =
24155
50
                AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
24156
46
          if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
24157
46
            TraitTy = ConstArrayTy->getElementType();
24158
50
        if (TraitTy.isNull() ||
24159
50
            
!(46
Context.hasSameUnqualifiedType(TraitTy,
24160
46
                                             DSAStack->getOMPAlloctraitT()) ||
24161
46
              
Context.typesAreCompatible(TraitTy, 0
DSAStack0
->getOMPAlloctraitT(),
24162
4
                                         /*CompareUnqualified=*/true))) {
24163
4
          Diag(D.AllocatorTraits->getExprLoc(),
24164
4
               diag::err_omp_expected_array_alloctraits)
24165
4
              << AllocatorTraitsExpr->getType();
24166
4
          continue;
24167
4
        }
24168
        // Do not map by default allocator traits if it is a standalone
24169
        // variable.
24170
46
        if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
24171
46
          DSAStack->addUsesAllocatorsDecl(
24172
46
              DRE->getDecl(),
24173
46
              DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
24174
46
      }
24175
50
    }
24176
491
    OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
24177
491
    NewD.Allocator = AllocatorExpr;
24178
491
    NewD.AllocatorTraits = AllocatorTraitsExpr;
24179
491
    NewD.LParenLoc = D.LParenLoc;
24180
491
    NewD.RParenLoc = D.RParenLoc;
24181
491
  }
24182
435
  return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24183
435
                                         NewData);
24184
435
}
24185
24186
OMPClause *Sema::ActOnOpenMPAffinityClause(
24187
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
24188
82
    SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
24189
82
  SmallVector<Expr *, 8> Vars;
24190
126
  for (Expr *RefExpr : Locators) {
24191
126
    assert(RefExpr && "NULL expr in OpenMP shared clause.");
24192
126
    if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
24193
      // It will be analyzed later.
24194
28
      Vars.push_back(RefExpr);
24195
28
      continue;
24196
28
    }
24197
24198
98
    SourceLocation ELoc = RefExpr->getExprLoc();
24199
98
    Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
24200
24201
98
    if (!SimpleExpr->isLValue()) {
24202
4
      Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24203
4
          << 1 << 0 << RefExpr->getSourceRange();
24204
4
      continue;
24205
4
    }
24206
24207
94
    ExprResult Res;
24208
94
    {
24209
94
      Sema::TentativeAnalysisScope Trap(*this);
24210
94
      Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
24211
94
    }
24212
94
    if (!Res.isUsable() && 
!isa<OMPArraySectionExpr>(SimpleExpr)56
&&
24213
94
        
!isa<OMPArrayShapingExpr>(SimpleExpr)14
) {
24214
2
      Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24215
2
          << 1 << 0 << RefExpr->getSourceRange();
24216
2
      continue;
24217
2
    }
24218
92
    Vars.push_back(SimpleExpr);
24219
92
  }
24220
24221
82
  return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
24222
82
                                   EndLoc, Modifier, Vars);
24223
82
}
24224
24225
OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
24226
                                       SourceLocation KindLoc,
24227
                                       SourceLocation StartLoc,
24228
                                       SourceLocation LParenLoc,
24229
204
                                       SourceLocation EndLoc) {
24230
204
  if (Kind == OMPC_BIND_unknown) {
24231
5
    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
24232
5
        << getListOfPossibleValues(OMPC_bind, /*First=*/0,
24233
5
                                   /*Last=*/unsigned(OMPC_BIND_unknown))
24234
5
        << getOpenMPClauseName(OMPC_bind);
24235
5
    return nullptr;
24236
5
  }
24237
24238
199
  return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
24239
199
                               EndLoc);
24240
204
}
24241
24242
OMPClause *Sema::ActOnOpenMPXDynCGroupMemClause(Expr *Size,
24243
                                                SourceLocation StartLoc,
24244
                                                SourceLocation LParenLoc,
24245
412
                                                SourceLocation EndLoc) {
24246
412
  Expr *ValExpr = Size;
24247
412
  Stmt *HelperValStmt = nullptr;
24248
24249
  // OpenMP [2.5, Restrictions]
24250
  //  The ompx_dyn_cgroup_mem expression must evaluate to a positive integer
24251
  //  value.
24252
412
  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_ompx_dyn_cgroup_mem,
24253
412
                                 /*StrictlyPositive=*/false))
24254
0
    return nullptr;
24255
24256
412
  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
24257
412
  OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
24258
412
      DKind, OMPC_ompx_dyn_cgroup_mem, LangOpts.OpenMP);
24259
412
  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
24260
300
    ValExpr = MakeFullExpr(ValExpr).get();
24261
300
    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
24262
300
    ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
24263
300
    HelperValStmt = buildPreInits(Context, Captures);
24264
300
  }
24265
24266
412
  return new (Context) OMPXDynCGroupMemClause(
24267
412
      ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
24268
412
}
24269
24270
OMPClause *Sema::ActOnOpenMPDoacrossClause(
24271
    OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc,
24272
    SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
24273
123
    SourceLocation LParenLoc, SourceLocation EndLoc) {
24274
24275
123
  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
24276
123
      DepType != OMPC_DOACROSS_source && 
DepType != OMPC_DOACROSS_sink90
&&
24277
123
      
DepType != OMPC_DOACROSS_sink_omp_cur_iteration36
&&
24278
123
      
DepType != OMPC_DOACROSS_source_omp_cur_iteration19
&&
24279
123
      
DepType != OMPC_DOACROSS_source4
) {
24280
4
    Diag(DepLoc, diag::err_omp_unexpected_clause_value)
24281
4
        << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
24282
4
    return nullptr;
24283
4
  }
24284
24285
119
  SmallVector<Expr *, 8> Vars;
24286
119
  DSAStackTy::OperatorOffsetTy OpsOffs;
24287
119
  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
24288
119
  DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
24289
119
      *this,
24290
119
      DepType == OMPC_DOACROSS_source ||
24291
119
          
DepType == OMPC_DOACROSS_source_omp_cur_iteration86
||
24292
119
          
DepType == OMPC_DOACROSS_sink_omp_cur_iteration71
,
24293
119
      VarList, DSAStack, EndLoc);
24294
119
  Vars = VarOffset.Vars;
24295
119
  OpsOffs = VarOffset.OpsOffs;
24296
119
  TotalDepCount = VarOffset.TotalDepCount;
24297
119
  auto *C = OMPDoacrossClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24298
119
                                      DepType, DepLoc, ColonLoc, Vars,
24299
119
                                      TotalDepCount.getZExtValue());
24300
119
  if (DSAStack->isParentOrderedRegion())
24301
117
    DSAStack->addDoacrossDependClause(C, OpsOffs);
24302
119
  return C;
24303
123
}
24304
24305
OMPClause *Sema::ActOnOpenMPXAttributeClause(ArrayRef<const Attr *> Attrs,
24306
                                             SourceLocation StartLoc,
24307
                                             SourceLocation LParenLoc,
24308
34
                                             SourceLocation EndLoc) {
24309
34
  return new (Context) OMPXAttributeClause(Attrs, StartLoc, LParenLoc, EndLoc);
24310
34
}
24311
24312
OMPClause *Sema::ActOnOpenMPXBareClause(SourceLocation StartLoc,
24313
48
                                        SourceLocation EndLoc) {
24314
48
  return new (Context) OMPXBareClause(StartLoc, EndLoc);
24315
48
}